Log plot with error bars in matplotlib doesn't work - python

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:

Related

Why aren't both subplots showing tick marks in matplotlib?

So I'm trying to plot some data via a scatter graph, and I would expect matplotlib to automatically add tick marks, which it does do on the first subplot. However, the second subplot does not have ticks with labels added automatically. I have tried setting the ticks myself explicitly which didn't work (using xticks and xticklabels).
Below is my code:
axs[0].scatter(dates, yvar, color="black", label="Data")
axs[0].plot(dates, predictions, color="blue", label="Predicted Value")
axs[1].scatter(predictions, yvar, color="red", label="Prediction vs Data")
plt.xticks(())
plt.yticks(())
fig.legend()
plt.show()
This code, trying to replicate your problem, behaves as expected. It produces the matplotlib.pyplot.xticks:
Try to call your legend with each ax individually
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 360, 1)
y = np.sin(2 * x * np.pi / 180)
z = np.cos(2 * x * np.pi / 180)
fig, ax = plt.subplots(2)
ax[0].scatter(x, y, label='label1')
ax[0].plot(x, z, label='label2')
ax[1].scatter(y, z, label='label3')
ax[0].legend()
ax[1].legend()
plt.tight_layout()
plt.show()

Issue with indenting line of code in scatter plot in matplotlib/pyplot

I've been learning how to make scatter plots with groups, and I'm using this tutorial as a reference. I'm currently trying to create this scatter plot, however, I've noticed there is no indentation in line 19 in the code:
import numpy as np
import matplotlib.pyplot as plt
# Create data
N = 60
g1 = (0.6 + 0.6 * np.random.rand(N), np.random.rand(N))
g2 = (0.4+0.3 * np.random.rand(N), 0.5*np.random.rand(N))
g3 = (0.3*np.random.rand(N),0.3*np.random.rand(N))
data = (g1, g2, g3)
colors = ("red", "green", "blue")
groups = ("coffee", "tea", "water")
# Create plot
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, axisbg="1.0")
for data, color, group in zip(data, colors, groups):
x, y = data
ax.scatter(x, y, alpha=0.8, c=color, edgecolors='none', s=30, label=group)
plt.title('Matplot scatter plot')
plt.legend(loc=2)
plt.show()
and I receive the following error messsage:
File "<ipython-input-2-58c0796c9f65>", line 19
x,y=data
^
IndentationError: expected an indented block
Therefore, I indented line 19, as such:
for data, color, group in zip(data, colors, groups):
x, y = data
ax.scatter(x, y, alpha=0.8, c=color, edgecolors='none', s=30, label=group)
but I get AttributeErrors after running the code.
As a reference, I've been using the first batch of code in Joe Kington's superb answer in this question Scatter plots in Pandas/Pyplot: How to plot by category, and followed the indentation pattern, but I'm lost with my scatter plot. Where did I go wrong here?
You must also indent the next line (ax.scatter(x, y, alpha=0.8, c=color, edgecolors='none', s=30, label=group). The following code should work:
import numpy as np
import matplotlib.pyplot as plt
# Create data
N = 60
g1 = (0.6 + 0.6 * np.random.rand(N), np.random.rand(N))
g2 = (0.4+0.3 * np.random.rand(N), 0.5*np.random.rand(N))
g3 = (0.3*np.random.rand(N),0.3*np.random.rand(N))
data = (g1, g2, g3)
colors = ("red", "green", "blue")
groups = ("coffee", "tea", "water")
# Create plot
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
for data, color, group in zip(data, colors, groups):
x, y = data
ax.scatter(x, y, alpha=0.8, c=color, edgecolors='none', s=30, label=group)
plt.title('Matplot scatter plot')
plt.legend(loc=2)
plt.show()

Hide radial tick labels matplotlib

I'm trying to plot a polar plot with this code:
import numpy as np
import matplotlib.pylab as plt
def power(angle, l, lam):
return 1/(lam) * ((np.cos(np.pi*l*np.cos(angle)/lam) - np.cos(np.pi*l/lam))/np.sin(angle))**2
fig = plt.figure(1)
ax = fig.add_subplot(111, projection='polar')
theta = np.linspace(0.001, 2*np.pi, 100)
P1 = power(theta, 1, 5)
ax.plot(theta, P1, color='r', linewidth=3)
plt.savefig('1.png')
and I get this plot:
I would like to change 2 things. The first and more important one is to hide the radial tick labels (I just want to show the general form of the plot).
If possible, how can I choose the vertical axis to correspond to 0°?
Thanks for your help.
You can use set_yticklabels() to remove the radial ticks and set_theta_zero_location() to change the zero location:
fig = plt.figure(1)
ax = fig.add_subplot(111, projection='polar')
ax.plot(theta, P1, color='r', linewidth=3)
ax.set_yticklabels([])
ax.set_theta_zero_location('N')
plt.show()
You might also want to change the direction of the azimuthal axis:
ax.set_theta_direction(-1)
You can set the theta zero position with ax.set_theta_zero_location('N').
To modify the r tick labels, you could do something like
for r_label in ax.get_yticklabels():
r_label.set_text('')
If you want to remove them entirely, do ax.set_yticklabels([]).
More methods can be found in the PolarAxes documentation.

incorrect Colorbar for log values in scatter plot

I want to use a scatter plot to describe the relationship between X, Y and Z. Z is p-value so it is better to denote it as log values.
Following the instructions here, I can plot a logarithmic scatter plot, but the color bar seems wrong. The color bar is almost totally blue, but there should be some red! Below is the figure and my codes.
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.colors import LogNorm
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax1.set_title("P-value")
Z1 = pos_spearmanr['pval']
X = pos_spearmanr['X']
Y = pos_spearmanr['Y']
im = ax1.scatter(X,
Y,
edgecolors=None,
c=Z1,
norm=LogNorm(),
cmap=plt.get_cmap('bwr'), alpha=0.2)
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax1.set_xlim(0, 1)
ax1.set_ylim(0, 1)
cbar = fig.colorbar(im,ax=ax1)

Residual plot not aligned with main graph

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.

Categories

Resources