I have a list and i want to plot the list in such a way that for certain range of x axis the lines are dotted while for other range it is solid.
e.g.:
y=[11,22,33,44,55,66,77,88,99,100]
x=[1,2,3,4,5,6,7,8,9,10]
i did this:
if i range(4,8):
plt.plot(x,y,marker='D')
else :
plt.plot(x,y,'--')
plt.show()
but this doesnot work.
can someone help?
Slice the data into 3 intervals
import matplotlib.pyplot as plt
import numpy as np
# Data for plotting
x = [1,2,3,4,5,6,7,8,9,10]
y = [11,22,33,44,55,66,77,88,99,100]
fig, ax = plt.subplots()
m, n = 4, 8
x1, x2, x3 = x[:m+1], x[m:n+1], x[n:]
y1, y2, y3 = y[:m+1], y[m:n+1], y[n:]
ax.plot(x1, y1, color='red', linestyle='solid', marker='D')
ax.plot(x2, y2, color='blue', linestyle='dashed')
ax.plot(x3, y3, color='red', linestyle='solid', marker='D')
plt.show()
Here is a solution with the same colours for the whole line:
import matplotlib.pyplot as plt
x = [1,2,3,4,5,6,7,8,9,10]
y = [11,22,33,44,55,66,77,88,99,100]
fig, ax = plt.subplots()
x1, y1 = x[:4], y[:4]
x2, y2 = x[3:8], y[3:8]
x3, y3 = x[7:], y[7:]
ax.plot(x1, y1, marker='D', color='b')
ax.plot(x2, y2, '--', color='b')
ax.plot(x3, y3, marker='D', color='b')
Change line characteristics based on the value of x:
import numpy as np
from matplotlib import pyplot as plt
Make arrays of the lists;
y = np.array([11,22,33,44,55,66,77,88,99,100])
x = np.array([1,2,3,4,5,6,7,8,9,10])
make a boolean array based on your condition(s);
dashed = np.logical_or(x<4,x>=8)
use the boolean array to filter the data when you plot.
plt.plot(x[~dashed],y[~dashed],color='blue',marker='D')
plt.plot(x[dashed],y[dashed],color='blue',ls='--')
Related
Is there any way to extend gridlines into the data area of a 3d plot?
I have this plot, and all of the plots are at 1 for the z-axis (confirmed by checking the array values), but this doesn't look obvious to me. I'm hoping that adding internal gridlines will help to clarify it. I generated it with this code:
fig = plt.figure(figsize = (10,10))
ax = plt.axes(projection ='3d')
x, y, z = np.array(list1), np.array(list2), np.array(list3)
c = x+y
ax.scatter(x, y, z, c=c)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.set_title(f'Title')
plt.show()
Thanks!
Option 1
If all the points are at a single Z value, then only plot a single plane
import matplotlib.pyplot as plt
import numpy as np
# test data
np.random.seed(365)
x, y = np.random.randint(2500, 20000, size=(7, )), np.random.randint(0, 1600, size=(7, ))
fig, ax = plt.subplots(figsize=(6, 6))
ax.scatter(x=x, y=y)
ax.set(title='Plane at Z=1')
Option 2
Plot lines at the axis ticks
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(10, 10))
ax = plt.axes(projection='3d')
# test data
np.random.seed(365)
x, y, z = np.random.randint(2500, 20000, size=(7, )), np.random.randint(0, 1600, size=(7, )), np.ones(7)
c = x+y
ax.scatter(x, y, z, c=c)
# get the x and y tick locations
x_ticks = ax.get_xticks()
y_ticks = ax.get_yticks()
# add lines
for y1 in y_ticks:
x1, x2 = x_ticks[0], x_ticks[-1]
ax.plot([x1, x2], [y1, y1], [1, 1], color='lightgray')
for x1 in x_ticks:
y1, y2 = y_ticks[0], y_ticks[-1]
ax.plot([x1, x1], [y1, y2], [1, 1], color='lightgray')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.set_title(f'Title')
plt.show()
I want to make the lines of the following graph smooth. I tried to search and it seems that we have to represent the x-axis in terms of a float or some type such as date time. Here since the x-axis are just labels, I could not figure out how I should change my code. Any help is appreciated.
import matplotlib.pyplot as plt
x1 = [">1", ">10",">20"]
y1 = [18,8,3]
y2 = [22,15,10]
y3=[32,17,11]
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.scatter(x1, y1, color='blue', label='Heuristic')
ax1.scatter(x1, y2, color='green', label='SAFE')
ax1.scatter(x1, y3, color='red', label='discovRE')
plt.plot(x1, y2, '.g:')
plt.plot(x1, y1, '.b:')
plt.plot(x1, y3, '.r:')
plt.ylabel('False Positives',fontsize=8)
plt.xlabel('Function instruction sizes',fontsize=8)
plt.legend()
plt.show()
Following is the graph that I get right now.
Maybe you can fit a curve to 'smooth' the curve
import matplotlib.pyplot as plt
x1 = [">1", ">10",">20"]
y1 = [18,8,3]
y2 = [22,15,10]
y3=[32,17,11]
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.scatter(x1, y1, color='blue', label='Heuristic')
ax1.scatter(x1, y2, color='green', label='SAFE')
ax1.scatter(x1, y3, color='red', label='discovRE')
buff_x = np.linspace(0,2,100)
def reg_func(y):
params = np.polyfit(range(len(y)),y,2)
return np.polyval(params,buff_x)
plt.plot(buff_x, reg_func(y2), 'g',linestyle='dotted')
plt.plot(buff_x, reg_func(y1), 'b',linestyle='dotted')
plt.plot(buff_x, reg_func(y3), 'r',linestyle='dotted')
plt.ylabel('False Positives',fontsize=8)
plt.xlabel('Function instruction sizes',fontsize=8)
plt.legend()
plt.show()
as you can see, I use a function reg_func to fit your data, and plot the predicted curves
How do you plot arrays of different lengths but extend properly on the x-axis? The code below generates 2 data sets, the second one being shorter. I run an interpolation over each set resampling the data with multiple samples per data point. When I plot all of the data the data sets that are shorter don't extend to the end of the plot. I don't want subplots, I need to overlay the data onto each other.
#!/usr/bin/env python3
from scipy import interpolate
import matplotlib.pyplot as plt
import numpy as np
num_points = 100
# Generate an array of data, interpolate, re-sample and graph
x1 = np.arange(0, num_points)
y1 = np.cos(x1)
f1 = interpolate.interp1d(x1, y1, kind='cubic')
xnew1 = np.arange(0, num_points - 1, 0.2)
ynew1 = f1(xnew1)
plt.plot(x1, y1, color='g', label='input 1')
plt.plot(x1, y1, 'o', color='g')
plt.plot(xnew1, ynew1, color='m', label='interp 1')
plt.plot(xnew1, ynew1, '+', color='m')
# Generate ana array different size of data, interpolate, re-sample and graph
x2 = np.arange(0, num_points/2)
y2 = np.sin(x2)
f2 = interpolate.interp1d(x2, y2, kind='cubic')
xnew2 = np.arange(0, (num_points/2) - 1, 0.2)
ynew2 = f2(xnew2)
plt.plot(x2, y2, color='k', label='input 2')
plt.plot(x2, y2, 'o', color='k')
plt.plot(xnew2, ynew2, color='r', label='interp 2')
plt.plot(xnew2, ynew2, '+', color='r')
plt.legend(loc='upper left')
plt.show()
If I am understanding correctly, this can be done by using two different axes which share the same y-axis, as outlined in this matplotlib example.
In your case you can accomplish this by making the following modifications:
from scipy import interpolate
import matplotlib.pyplot as plt
import numpy as np
num_points = 100
# Generate an array of data, interpolate, re-sample and graph
x1 = np.arange(0, num_points)
y1 = np.cos(x1)
f1 = interpolate.interp1d(x1, y1, kind='cubic')
xnew1 = np.arange(0, num_points - 1, 0.2)
ynew1 = f1(xnew1)
fig, ax1 = plt.subplots() # Create the first axis
ax1.plot(x1, y1, color='g', label='input 1')
ax1.plot(x1, y1, 'o', color='g')
ax1.plot(xnew1, ynew1, color='m', label='interp 1')
ax1.plot(xnew1, ynew1, '+', color='m')
ax2 = ax1.twiny() # Create a twin which shares the y-axis
# Generate an array different size of data, interpolate, re-sample and graph
x2 = np.arange(0, num_points/2)
y2 = np.sin(x2)
f2 = interpolate.interp1d(x2, y2, kind='cubic')
xnew2 = np.arange(0, (num_points/2) - 1, 0.2)
ynew2 = f2(xnew2)
ax2.plot(x2, y2, color='k', label='input 2')
ax2.plot(x2, y2, 'o', color='k')
ax2.plot(xnew2, ynew2, color='r', label='interp 2')
ax2.plot(xnew2, ynew2, '+', color='r')
plt.figlegend(loc='upper left', bbox_to_anchor=(0.065, 0.3, 0.5, 0.5))
plt.show()
This will give you something that looks like
Edit
In order to properly display the legend you can construct one legend for all the subplots, as outlined in this demo. Note that using this method will require some manhandling of the bounding box for the legend, and there are much cleaner ways to do this than specifying a 4-tuple of floats as I have in the line
plt.figlegend(loc='upper left', bbox_to_anchor=(0.065, 0.3, 0.5, 0.5))
I would like to fill the area between the curve y1=x^3 and then line y2=3x-2.
Below is code I have that will do this, however, I want to place the restriction that y1 < y2 (which I have done with the where option of fill_between) and that x<1.
The problem that occurs with the code below is that the area between the curve is filled for x>1. I would like to plot these graphs on the range [-2.5,2.5]. How do I get matplotlib to stop filling between the curves for x>1?
My code:
import matplotlib.pyplot as plot
import numpy as np
x = np.linspace(-2.5, 2.5, 100)
y1 = np.array([i**3 for i in x])
y2 = np.array([3*i-2 for i in x])
fig = plot.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(x, y1, label=r"$y=x^3$")
ax.plot(x, y2, label=r"$y=3x-2$")
ax.spines['left'].set_position('center')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('center')
ax.spines['top'].set_color('none')
ax.spines['left'].set_smart_bounds(True)
ax.spines['bottom'].set_smart_bounds(True)
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.fill_between(x, y1, y2, where=y2<y1, facecolor='green')
ax.legend()
plot.show()
I got it. The easiest fix is to define 3 new variables, u,v, and w, where u holds the x values for v and w, and v = x^3, w=3x-2.
u=x[x<1]
v=y1[y1<1]
w=y2[y2<1]
Then plot these values with fill_between:
ax.fill_between(u, v, w, where=w<v, facecolor='green')
I have a script to plot count rates with the raw source data, background and source with background corrected that I would like to display one below the other. However, I would also like the three separate subplots to have the same y-axis limits and scale in order to aid comparison of the three. Since I will be applying it to numerous datasets, I can't really just set all three to have the same limits manually each time.
Here's a MWE:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(11)
y1 = np.arange(1,6.1,0.5)
y2 = np.arange(11)
y3 = np.arange(4,9.1,0.5)
plt.subplot(3,1,1)
plt.errorbar(x, y1, yerr=0.5)
plt.subplot(3,1,2)
plt.errorbar(x, y2, yerr=1.0)
plt.subplot(3,1,3)
plt.errorbar(x, y3, yerr=0.5)
plt.show()
Do you mean this?
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(11)
y1 = np.arange(1,6.1,0.5)
y2 = np.arange(11)
y3 = np.arange(4,9.1,0.5)
plt.subplot(3,1,1)
plt.errorbar(x, y1, yerr=0.5)
ymin, ymax = plt.gca().get_ylim()
plt.subplot(3,1,2)
plt.errorbar(x, y2, yerr=1.0)
plt.ylim([ymin, ymax])
plt.subplot(3,1,3)
plt.errorbar(x, y3, yerr=0.5)
plt.ylim([ymin, ymax])
plt.show()