Matplotlib.pyplot.hist()非常缓慢

22

我正在绘制一个包含大约1,000个唯一值的数组中的10,000项。绘图已运行了半小时。我确保了代码的其余部分工作正常。

这很慢吗?这是我第一次使用pyplot绘制直方图。


是的,我认为那非常慢。实际上这取决于你选择了多少个箱子,但是例如对于1000个箱子,我可以在一两秒内绘制出10000个随机生成的值。使用Python 2、笔记本电脑核心Intel i5操作系统Ubuntu 14.04。展示一些代码会让事情变得更容易。 - ljetibo
1
实际上,我只是通过减少箱子的数量来解决了这个问题。谢谢。 - Fenwick
1
你确定你在使用正确的列数据类型吗?我之前使用了字符串而不是整数,这是我的纯粹错误。 - piedpiper
9个回答

27

为了快速使用matplotlib绘制直方图,您需要在pyplot.hist中传递histtype='step'参数。例如:

要使用matplotlib快速绘制直方图,您需要将histtype='step'参数传递给pyplot.hist函数。例如:


(注:原文中的“plot histograms”被翻译成了“绘制直方图”,但这并不会改变原义)
plt.hist(np.random.exponential(size=1000000,bins=10000))
plt.show()

绘制需要大约15秒钟,并且在平移或缩放时需要大约5-10秒钟才能更新。

相比之下,使用histtype='step'绘图:

plt.hist(np.random.exponential(size=1000000),bins=10000,histtype='step')
plt.show()

绘图几乎立即完成,并且可以无延迟地平移和缩放。


1
这确实比你说的要快得多(我看到的时间与你一样)。但是使用histtype='step'绘制的图形看起来非常不同。 - demented hedgehog
1
@dementedhedgehog 是的,他们确实会。我猜这取决于你从事哪个学科。在高能物理中,步骤样式是常规。我之前在 matplotlib 页面上开了一个问题来讨论这个问题:https://github.com/matplotlib/matplotlib/issues/7121。 - user545424

15

将numpy数组展平后,制作直方图会非常快。请尝试下面的示例代码:

import numpy as np

array2d = np.random.random_sample((512,512))*100
plt.hist(array2d.flatten())
plt.hist(array2d.flatten(), bins=1000)

2
遇到了同样的问题,这个解决方案非常有效。 - Jarom
这应该是被接受的答案。相比于无反应,它可以瞬间处理100k个值。如果绘制多个直方图,array2d.flatten()会导致直方图绘制成一个整体。解决方法是分别添加每一列。 - Eilon Baer
这应该是被接受的答案。远远优于那些得到更多赞的答案。 - jbcd13
这太棒了!但我想知道为什么将数组展平会在执行时间上有如此巨大的改善? - Khoa LT

7

在代码中引入seaborn可能会导致pyplot.hist执行时间非常长。

如果问题是由seaborn引起的,可以通过重置matplotlib设置来解决:

import seaborn as sns
sns.reset_orig()

3

对于我来说,问题在于pd.Series的数据类型(比如S)是'object'而不是'float64'。我使用S = np.float64(S)之后,plt.hist(S)就非常快了。


更改pandas.Series类型的正确方法是使用.astype()函数: S.astype('float64') - Trenton McKinney

2

由于多个答案已经提到了使用 pandas.hist() 时速度慢的问题,需要注意的是这可能是由于处理非数值数据所导致的。这个问题可以通过使用 value_counts() 很容易地解决:

df['colour'].value_counts().plot(kind='bar')

贡献者


1

我在使用Pandas的.hist()方法时遇到了同样的问题。对我来说解决方案是:

pd.to_numeric(df['your_data']).hist()

立即生效。


0
对我来说,在调用hist之后调用figure.canvas.draw()才能立即更新,也就是说,hist实际上很快(在计时后发现),但在图形更新前会有几秒钟的延迟。我是在jupyter lab单元格(qt5后端)中的matplotlib回调函数内调用hist的。

0
如果您正在使用pandas,请确保在plt.hist()中传递的数据是一维系列而不是数据框。这对我很有帮助。

0

有没有人遇到我遇到的问题 - (完全是我的错 :) )

如果你正在处理数字,请确保在从CSV读取时,数据类型是int / float,而不是string。

values_arr = .... .flatten().astype('float')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接