【问题标题】:Python: Matplotlib - probability plot for several data setPython:Matplotlib - 几个数据集的概率图
【发布时间】:2011-09-13 15:47:24
【问题描述】:

我有几个数据集(分布)如下:

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 进行绘图。

【问题讨论】:

  • 如果您准确描述如何将您的数据集转换为您想要绘制的内容,那么帮助您做到这一点会容易一些。

标签: python numpy matplotlib probability percentile


【解决方案1】:

我不完全清楚你想要什么,所以我猜,这里...

您希望“概率/百分位数”值是累积直方图吗?

所以对于一个情节,你会有这样的东西吗? (用上面显示的标记绘制它,而不是更传统的阶梯图......)

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

【讨论】:

  • 不错!顺便说一句,你有没有考虑将其中一些送到画廊?有一半的时间我发现弄清楚如何在 matplotlib 中做某事的最快方法是浏览图库以查找看起来像它的东西。
  • @Joe:累积频率和百分位数一样吗?我需要检查一下。您几乎解决了我的问题,我正在到处调整以处理数据表。
  • @siva - 不,他们不是。我不应该使用 100 作为样本大小!这使它非常具有误导性! (抱歉!)但是,将累积频率值表示为百分位数相当简单。您只需按数据集中的样本数进行归一化即可。
  • @Joe:您的 n=100 示例非常有用。学习了一些关于 matplotlib 的基础知识。谢谢。另外,您将如何规范化数据集?你能展示一下吗?我是否必须逐个找到 0-100 的百分位数,并将其与数据的最小值和最大值范围进行对比?
  • @siva - 查看底部的编辑。希望这更清楚一点!
猜你喜欢
  • 2015-09-02
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 2019-11-07
  • 1970-01-01
  • 2020-11-17
  • 2018-11-29
  • 1970-01-01
相关资源
最近更新 更多