Python:Matplotlib - 多数据集概率图
我有几个数据集(分布),如下所示:
set1 = [1,2,3,4,5]
set2 = [3,4,5,6,7]
set3 = [1,3,4,5,8]
我想用这些数据集画一个散点图,y轴表示概率(也就是数据集的百分位数:0%-100%),x轴表示数据集的名称。在JMP软件中,这个图叫做“分位数图”。
大概是这样的效果:

请教教我。谢谢。
[编辑]
我的数据是这样的csv格式:
使用JMP分析工具,我可以画出概率分布图(QQ图/正态分位数图,下面的图就是这个):
我觉得Joe Kington几乎解决了我的问题,但我想知道如何将原始的csv数据处理成概率或百分位数的数组。
我这样做是为了在Python中自动化一些统计分析,而不是依赖JMP来绘图。
1 个回答
11
我不太明白你具体想要什么,所以我来猜一下...
你想要“概率/百分位数”的值是一个累积直方图吗?
那么对于一个单独的图表,你想要的可能是这样的?(像你上面展示的那样用标记来绘制,而不是更传统的阶梯图...)
import scipy.stats
import numpy as np
import matplotlib.pyplot as plt
# 100 values from a normal distribution with a std of 3 and a mean of 0.5
data = 3.0 * np.random.randn(100) + 0.5
counts, start, dx, _ = scipy.stats.cumfreq(data, numbins=20)
x = np.arange(counts.size) * dx + start
plt.plot(x, counts, 'ro')
plt.xlabel('Value')
plt.ylabel('Cumulative Frequency')
plt.show()
如果这大致是你想要的单个图表,有很多方法可以在一个图形上制作多个图表。最简单的就是使用子图。
在这里,我们将生成一些数据集,并在不同的子图上用不同的符号绘制它们...
import itertools
import scipy.stats
import numpy as np
import matplotlib.pyplot as plt
# Generate some data... (Using a list to hold it so that the datasets don't
# have to be the same length...)
numdatasets = 4
stds = np.random.randint(1, 10, size=numdatasets)
means = np.random.randint(-5, 5, size=numdatasets)
values = [std * np.random.randn(100) + mean for std, mean in zip(stds, means)]
# Set up several subplots
fig, axes = plt.subplots(nrows=1, ncols=numdatasets, figsize=(12,6))
# Set up some colors and markers to cycle through...
colors = itertools.cycle(['b', 'g', 'r', 'c', 'm', 'y', 'k'])
markers = itertools.cycle(['o', '^', 's', r'$\Phi$', 'h'])
# Now let's actually plot our data...
for ax, data, color, marker in zip(axes, values, colors, markers):
counts, start, dx, _ = scipy.stats.cumfreq(data, numbins=20)
x = np.arange(counts.size) * dx + start
ax.plot(x, counts, color=color, marker=marker,
markersize=10, linestyle='none')
# Next we'll set the various labels...
axes[0].set_ylabel('Cumulative Frequency')
labels = ['This', 'That', 'The Other', 'And Another']
for ax, label in zip(axes, labels):
ax.set_xlabel(label)
plt.show()
如果我们想让它看起来像一个连续的图表,我们可以把子图挤在一起,并关闭一些边界。在调用 plt.show()
之前只需添加以下内容:
# Because we want this to look like a continuous plot, we need to hide the
# boundaries (a.k.a. "spines") and yticks on most of the subplots
for ax in axes[1:]:
ax.spines['left'].set_color('none')
ax.spines['right'].set_color('none')
ax.yaxis.set_ticks([])
axes[0].spines['right'].set_color('none')
# To reduce clutter, let's leave off the first and last x-ticks.
for ax in axes:
xticks = ax.get_xticks()
ax.set_xticks(xticks[1:-1])
# Now, we'll "scrunch" all of the subplots together, so that they look like one
fig.subplots_adjust(wspace=0)
希望这能对你有所帮助!
编辑:如果你想要百分位数值,而不是累积直方图(我真的不应该用100作为样本大小!),这也很简单。
只需像这样做(使用 numpy.percentile
而不是手动归一化):
# Replacing the for loop from before...
plot_percentiles = range(0, 110, 10)
for ax, data, color, marker in zip(axes, values, colors, markers):
x = np.percentile(data, plot_percentiles)
ax.plot(x, plot_percentiles, color=color, marker=marker,
markersize=10, linestyle='none')