Force pyplot subplots to use the same y-axis scale - python

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()

Related

How to make dotted and bold lines in the same plot

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='--')

Making the lines of the scatter plot smooth in MatPlotlib

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

Multiple independent lines in the same 3D Axes

I would like to draw multiple independent lines in a 3D plot in Python. It looks like: .
I am new at Python. Would you help me?
You have to work with matplotlib library (mplot3d package).
Here is a little example of 3dr plot with lines:
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
# make 3d axes
fig = plt.figure()
ax = fig.gca(projection='3d')
# test data
x = np.arange(-1., 1., .1)
y = np.arange(-1., 1., .1)
z1 = x + y
z2 = x * x
z3 = -y * y
# plot test data
ax.plot(x, y, z1)
ax.plot(x, y, z2)
ax.plot(x, y, z3)
# make labels
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()

adding 3D subplot to the set of 2D

I would like to add 3D plot in matplotlib 1.5.1 to the existing set of 2D plots (subplots). 2D plots work fine w/o 3D, but when I add 3D I'm getting an error that 'module' object has no attribute 'plot_surface'. I'd like to keep the code simple so I apply all commands to plt without creating new figure(there is also a way of adding labels with set_xlabel) which makes things ambiguous. The first 3 plots are simple 2D plots and the last is 3D.
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
y1 = u.nodes.concentration
x1 = u.nodes.x
plt.figure(figsize=(20, 10))
plt.subplot(221)
plt.title('Profile')
plt.xlabel('Range')
plt.ylabel('Concentration')
plt.plot(x1, y1, '-b')
# Inhibitor plt
y2 = z.nodes.concentration
x2 = z.nodes.x
plt.subplot(222)
plt.title('Profile')
plt.xlabel('Range')
plt.ylabel('Concentration')
plt.plot(x2, y2, '-r')
# Modulator plt
y3 = v.nodes.concentration
x3 = v.nodes.x
plt.subplot(223)
plt.title('Profile')
plt.xlabel('Range')
plt.ylabel('Concentration')
plt.plot(x3, y3, '-g')
#3D plot
plt.subplot(224, projection='3d')
# Grab data.
xx = u_fft_x_norm
yy = [i*time_period for i in xrange(1, times)]
zz = u_timespace
XX, YY = np.meshgrid(xx, yy)
ZZ = zz
# Plot a basic wireframe.
plt.plot_surface(XX, YY, ZZ, rstride=20, cstride=20)
plt.xlabel('Space')
plt.ylabel('Time')
plt.zlabel('Value')
plt.title('Profile')
I guess the error is self-explanatory. pyplot does not have a plot_surface command. There is also no indication that it should. Looking at all examples you find, plot_surface is an attribute of an axes.
ax = plt.subplot(224, projection='3d')
ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0, antialiased=False)

Filling between two lines with Matplotlib with 2 restrictions

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')

Categories