I am using Python 2.7 and have created a probability plot using the scipy.stats.probplot function. I want to change elements of the figure such as color/shape/size of the markers and the color/width of the best fit trend line. The documentation for probplot doesn't seem to have any option for changing these items.
Here is a my code (relevant portion):
#data is a list of y-values sampled from a lognormal distribution
d = getattr(stats, 'lognorm')
param = d.fit(data)
fig = plt.figure(figsize=[6, 6], dpi=100)
ax = fig.add_subplot(111)
fig = stats.probplot(data, dist='lognorm', sparams=param, plot=plt, fit=False)
#These next 3 lines just demonstrate that some plot features
#can be changed independent of the probplot function.
ax.set_title("")
ax.set_xlabel("Quantiles", fontsize=20, fontweight='bold')
ax.set_ylabel("Ordered Values", fontsize=20, fontweight='bold')
plt.show()
I tried grabbing the xy-data and creating my own scatter plot with ax.get_xydata() and fig.get_xydata(). However both of these failed as neither object has get_xydata() as a function. The figure that my code currently generates is:
The key is the combination with matplotlib.
You can access the line object from the axes object using ax.get_lines()
. Then, the properties can be changed accordingly.
You may have to figure out which index relates to the markers and which to the line(s). In the example below, the markers come first, hence:
ax.get_lines()[0].set_marker('p')
and the trend line is second:
ax.get_lines()[1].set_linewidth(12.0)
The example below is based on the probplot documentation:
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
nsample = 100
np.random.seed(7654321)
fig = plt.figure()
ax = fig.add_subplot(111)
x = stats.t.rvs(3, size=nsample)
res = stats.probplot(x, plot=plt)
ax.get_lines()[0].set_marker('p')
ax.get_lines()[0].set_markerfacecolor('r')
ax.get_lines()[0].set_markersize(12.0)
ax.get_lines()[1].set_linewidth(12.0)
plt.show()
The plot this creates looks ugly, but demonstrates the functionality:
The text (r^2=0.9616
) can be accessed through more general get_children
from the axes:
ax.get_children()[2].set_fontsize(22.0)
Without detailed knowledge of the indexing for these items, you can try with:
print ax.get_children()
which gives you:
[<matplotlib.lines.Line2D object at 0x33f4350>, <matplotlib.lines.Line2D object at 0x33f4410>,
<matplotlib.text.Text object at 0x33f4bd0>, <matplotlib.spines.Spine object at 0x2f2ead0>,
<matplotlib.spines.Spine object at 0x2f2e8d0>, <matplotlib.spines.Spine object at 0x2f2e9d0>,
<matplotlib.spines.Spine object at 0x2f2e7d0>, <matplotlib.axis.XAxis object at 0x2f2eb90>,
<matplotlib.axis.YAxis object at 0x2f37690>, <matplotlib.text.Text object at 0x2f45290>,
<matplotlib.text.Text object at 0x2f45310>, <matplotlib.text.Text object at 0x2f45390>,
<matplotlib.patches.Rectangle object at 0x2f453d0>]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With