Residual plot not aligned with main graph - python

What is wrong with my residual plot that is causing to not be aligned with my main graph? My code is below.
import matplotlib.pyplot as plt
from scipy import stats
import numpy as np
x = np.array([0.030956,0.032956,0.034956,0.036956,0.038956,0.040956])
y = np.array([10.57821088,11.90701212,12.55570876,13.97542486,16.05403248,16.36634177])
yerr = [0.101614114,0.363255259,0.057234211,0.09289917,0.093288198,0.420165796]
xerr = [0.00021]*len(x)
fig1 = plt.figure(1)
frame1=fig1.add_axes((.1,.3,.8,.6))
m, b = np.polyfit(x, y, 1)
print 'gradient',m,'intercept',b
plt.plot(x, m*x + b, '-', color='grey', alpha=0.5)
plt.plot(x,y,'.',color='black',markersize=6)
plt.errorbar(x,y,xerr=0,yerr=yerr,linestyle="None",color='black')
plt.ylabel('$1/\sqrt{F}$ $(N)$',fontsize=20)
plt.autoscale(enable=True, axis=u'both', tight=True)
plt.grid(False)
frame2=fig1.add_axes((.1,.1,.8,.2))
s = m*x+b #(np.sqrt(4*np.pi*8.85E-12)/2.23E-8)*x
difference = y-s
plt.plot(x, difference, 'ro')
frame2.set_ylabel('$Residual$',fontsize=20)
plt.xlabel('$2s+d_0$ $(m)$',fontsize=20)

you can specify the axis limits. the problem is that autoscale is moving your two plots differently. if you insert 2 lines of code, each specifying the axis limits, it will fix it.
plt.axis([.030,.0415, 10, 17]) #line 17
plt.axis([.030,.0415, -.6, .8]) #line 26
i believe this is what you're looking for.

Try using GridSpec.
from matplotlib import gridspec
fig = plt.figure()
gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1])
ax0 = plt.subplot(gs[0])
ax1 = plt.subplot(gs[1])
ax0.plot(x, m*x + b, '-', color='grey', alpha=0.5)
ax0.plot(x,y,'.',color='black',markersize=6)
ax1.plot(x, difference, 'ro')
And use set_ylabel instead of ylabel (which you use for plt for example) for axes.

Related

Logarithmic Ticks on Top and Right Spine

I am trying to make a visualization with logarithmic ticks on all sides of the box.
import numpy as np
import matplotlib.pyplot as plt
x = np.logspace(2, 5, 5)
y = 0.5*x**(-1/2)
y2 = 0.01*x**(-1/2)
y3 = 0.05*x**(-1/3)
fig, ax = plt.subplots()
ax.plot(x, y, 'o-', label="One")
ax.plot(x, y2, '*-', label="Two")
ax.plot(x, y3, '--', label="Three")
ax.set(
xlabel='Input',
xlim=(1e2, 1e5),
xscale='log',
ylabel='Output',
ylim=(1e-5, 1e-1),
yscale='log',
)
ax.tick_params(top=True, right=True) # <-- This didn't work how I expected.
ax.legend(loc='lower left');
I would like the associated minor tick marks on the top and right spine.
Any advice on how to make that happen?
Use the which parameter of Axes.tick_params:
ax.tick_params(which='both', top=True, right=True)
Output:

Seaborn plot with second y axis

i wanted to know how to make a plot with two y-axis so that my plot that looks like this :
to something more like this by adding another y-axis :
i'm only using this line of code from my plot in order to get the top 10 EngineVersions from my data frame :
sns.countplot(x='EngineVersion', data=train, order=train.EngineVersion.value_counts().iloc[:10].index);
I think you are looking for something like:
import matplotlib.pyplot as plt
x = [1,2,3,4,5]
y = [1000,2000,500,8000,3000]
y1 = [1050,3000,2000,4000,6000]
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.bar(x, y)
ax2.plot(x, y1, 'o-', color="red" )
ax1.set_xlabel('X data')
ax1.set_ylabel('Counts', color='g')
ax2.set_ylabel('Detection Rates', color='b')
plt.show()
Output:
#gdubs If you want to do this with Seaborn's library, this code set up worked for me. Instead of setting the ax assignment "outside" of the plot function in matplotlib, you do it "inside" of the plot function in Seaborn, where ax is the variable that stores the plot.
import seaborn as sns # Calls in seaborn
# These lines generate the data to be plotted
x = [1,2,3,4,5]
y = [1000,2000,500,8000,3000]
y1 = [1050,3000,2000,4000,6000]
fig, ax1 = plt.subplots() # initializes figure and plots
ax2 = ax1.twinx() # applies twinx to ax2, which is the second y axis.
sns.barplot(x = x, y = y, ax = ax1, color = 'blue') # plots the first set of data, and sets it to ax1.
sns.lineplot(x = x, y = y1, marker = 'o', color = 'red', ax = ax2) # plots the second set, and sets to ax2.
# these lines add the annotations for the plot.
ax1.set_xlabel('X data')
ax1.set_ylabel('Counts', color='g')
ax2.set_ylabel('Detection Rates', color='b')
plt.show(); # shows the plot.
Output:
Seaborn output example
You could try this code to obtain a very similar image to what you originally wanted.
import seaborn as sb
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
x = ['1.1','1.2','1.2.1','2.0','2.1(beta)']
y = [1000,2000,500,8000,3000]
y1 = [3,4,1,8,5]
g = sb.barplot(x=x, y=y, color='blue')
g2 = sb.lineplot(x=range(len(x)), y=y1, color='orange', marker='o', ax=g.axes.twinx())
g.set_xticklabels(g.get_xticklabels(), rotation=-30)
g.set_xlabel('EngineVersion')
g.set_ylabel('Counts')
g2.set_ylabel('Detections rate')
g.legend(handles=[Rectangle((0,0), 0, 0, color='blue', label='Nontouch device counts'), Line2D([], [], marker='o', color='orange', label='Detections rate for nontouch devices')], loc=(1.1,0.8))

Difference between axis('equal') and axis('scaled') in matplotlib

In the reference, they are described as:
axis('equal')
changes limits of x or y axis so that equal increments of x and y have the same length; a circle is
circular.:
axis('scaled')
achieves the same result by changing the dimensions of the plot box instead of the axis data limits.:
But I did not understand the part 'by changing the dimensions of the plot box'.
So I compared directly
import numpy as np
import matplotlib.pyplot as plt
plt.close('all')
x = np.array(np.linspace(-np.pi, np.pi))
y = np.sin(x)
ax1 = plt.subplot(2, 1, 1)
ax1 = plt.plot(x, y)
plt.axis('scaled')
ax1 = plt.subplot(2, 1, 2)
plt.plot(x, y)
plt.axis('equal')
There is only a slight difference that the width is shorter when plotted with plt.axis('scaled').
How can I know the difference better?
I think the difference becomes more apparent, if you use different data.
import numpy as np
import matplotlib.pyplot as plt
x = np.array(np.linspace(-np.pi, np.pi))
y = np.sin(x)*np.pi
ax1 = plt.subplot(2, 1, 1)
ax1 = plt.plot(x, y)
plt.axis('scaled')
ax1 = plt.subplot(2, 1, 2)
plt.plot(x, y)
plt.axis('equal')
plt.show()
So the difference is if the axes around the plot are changed according to the aspect, or if they stay the same as in a usual subplot and are scaled such, that the aspect of the plot data is equal.

With MatPlotLib, how do I apply autoscaled axes from one graph to a separate graph?

So I have a dataset I want to plot. In this case, I want to plot all the data on the same graph, and then graph each point in the set on its own graph, but keep the axis scale/limits the same for each graph.
So what I need to do is find the values of the autoscaled axis limits that were set for the full set of data, and apply those limits to the graph for each individual points.
I am and have been reading the mpl docs to see if theres any kind of function I can use that will return the axis limits values, but I haven't found anything so far.
Im using Python 3.4 with matplotlib
Thanks,
evamvid
Although it is possible to find the limits with
xmin, xmax = ax.get_xlim()
ymin, ymax = ax.get_ylim()
and set them on another axes with
ax2.set_xlim(xmin, xmax)
ax2.set_ylim(ymin, ymax)
it might be easier to use plt.subplots with sharex=True and sharey=True:
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(2015)
N = 5
x, y = np.random.randint(100, size=(2,N))
fig, axs = plt.subplots(nrows=2, ncols=3, sharex=True, sharey=True)
colors = np.linspace(0, 1, N)
axs[0,0].scatter(x,y, s=200, c=colors)
for i, ax in enumerate(axs.ravel()[1:]):
ax.scatter(x[i], y[i], s=200, c=colors[i], vmin=0, vmax=1)
plt.show()
Another option is to pass an axes to sharex and sharey:
ax3 = subplot(313, sharex=ax1, sharey=ax1)
For example,
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import itertools as IT
np.random.seed(2015)
N = 6
x, y = np.random.randint(100, size=(2,N))
colors = np.linspace(0, 1, N)
gs = gridspec.GridSpec(4, 2)
ax = plt.subplot(gs[0, :])
ax.scatter(x, y, s=200, c=colors)
for k, coord in enumerate(IT.product(range(1,4), range(2))):
i, j = coord
ax = plt.subplot(gs[i, j], sharex=ax, sharey=ax)
ax.scatter(x[k], y[k], s=200, c=colors[k], vmin=0, vmax=1)
plt.tight_layout()
plt.show()

Log plot with error bars in matplotlib doesn't work

I'm trying to create a plot with the following components:
Scatter plot
Line of best fit with error bars.
Y scaled to be log.
So this is a standard log linear plot saved to a png, but whilst I can get the scatter plot working I cannot get the fitted line to plot on the diagram. I just get one blob. Here is the code that I am using:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, xlim=(-2,2), ylim=(1,10E11))
ax.scatter(x, y, s=1, c='black')
line, = ax.semilogy([-0.5, 1], [-0.5*m+c, 1.0*m + c], color='red', linestyle='-', linewidth=2)
ax.errorbar(-0.5, -0.5*m+c, yerr=ser, marker='o', color='red')
ax.errorbar(1, m * 1.0 + c, yerr=ser, marker='o', color='green')
ax.set_yscale('log')
fig.savefig('log.png')
I get the scatter plot. and the log scale, but not the fitted line or the error bar.
x = np.array(x)
y = np.array(y)
~50,000 points
m = gradient = 2.38329162e+09
c = 1.24269722e+09
I've tried lots of variations, but I cannot seem to get the line plotted correctly. I cannot find one example of an error bar plot with log scale.
As an update, I could finally get the line working. It was due to the y heading below zero. However I cannot still get the error bars plotted. I only can get one whisker line plot (not four) and no horizontal joining lines.
matplotlib version: 1.2.0
Since you did not provide any number, I had to guess.
But this works, so your data might be weird (have you zoomed in to see if ser is not just really small?)
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
x = np.random.rand(500,1)*2 -1
y = np.random.rand(500,1)*1e10
m = gradient = 2.38329162e+09
c = 1.24269722e+09
ser = 1e10
fig = plt.figure()
ax = fig.add_subplot(111, xlim=(-2,2), ylim=(1,10E11))
ax.scatter(x, y, s=1, c='black')
ax.plot([-1, 1], [m * -1.0 + c, 1.0*m + c], color='red', linestyle='-', linewidth=2)
ax.errorbar(-1, m * -1.0 + c, yerr=(ser), marker='o', color='green')
ax.errorbar(1, m * 1.0 + c, yerr=(ser), marker='o', color='green')
ax.set_yscale('log')
fig.savefig('log.png')
Result:

Categories

Resources