使用 Matplotlib 在对数尺度上绘制直方图

Posted

技术标签:

【中文标题】使用 Matplotlib 在对数尺度上绘制直方图【英文标题】:plotting a histogram on a Log scale with Matplotlib 【发布时间】:2018-05-30 17:13:58 【问题描述】:

我有一个 Pandas DataFrame,它在 Series 中有以下值

x = [2, 1, 76, 140, 286, 267, 60, 271, 5, 13, 9, 76, 77, 6, 2, 27, 22, 1, 12, 7, 19, 81, 11, 173, 13, 7, 16, 19, 23, 197, 167, 1]

我被指示使用 Python 3.6 在 Jupyter 笔记本中绘制两个直方图。没出汗吧?

x.plot.hist(bins=8)
plt.show()

我选择了 8 个垃圾箱,因为这对我来说看起来最好。 我还被指示用 x 的对数绘制另一个直方图。

x.plot.hist(bins=8)
plt.xscale('log')
plt.show()

这个直方图看起来很糟糕。我做的不对吗?我试过摆弄情节,但我尝试过的一切似乎都让直方图看起来更糟。示例:

x.plot(kind='hist', logx=True)

除了将 X 的对数绘制为直方图外,我没有得到任何指示。

我真的很感激任何帮助!!!

作为记录,我已经导入了 pandas、numpy 和 matplotlib,并指定该图应该是内联的。

【问题讨论】:

直方图的“可怕之处”是什么? 最好的方法/解决方法就是plt.hist(np.log(x)) 【参考方案1】:

hist调用中指定bins=8意味着最小值和最大值之间的范围被平均分为8个bin。在线性尺度上相等的东西在对数尺度上是扭曲的。

您可以做的是指定直方图的 bin,使它们的宽度不相等,以使它们在对数刻度上看起来相等。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

x = [2, 1, 76, 140, 286, 267, 60, 271, 5, 13, 9, 76, 77, 6, 2, 27, 22, 1, 12, 7, 
     19, 81, 11, 173, 13, 7, 16, 19, 23, 197, 167, 1]
x = pd.Series(x)

# histogram on linear scale
plt.subplot(211)
hist, bins, _ = plt.hist(x, bins=8)

# histogram on log scale. 
# Use non-equal bin sizes, such that they look equal on log scale.
logbins = np.logspace(np.log10(bins[0]),np.log10(bins[-1]),len(bins))
plt.subplot(212)
plt.hist(x, bins=logbins)
plt.xscale('log')
plt.show()

【讨论】:

我会使用 logbins = np.geomspace(x.min(), x.max(), 8) 来保存所有这些日志的输入(并且 bins[0]、bins[-1] 只是最小和最大)。【参考方案2】:

这是另一种解决方案,无需使用子图或在同一图像中绘制两个东西。

import numpy as np
import matplotlib.pyplot as plt

def plot_loghist(x, bins):
  hist, bins = np.histogram(x, bins=bins)
  logbins = np.logspace(np.log10(bins[0]),np.log10(bins[-1]),len(bins))
  plt.hist(x, bins=logbins)
  plt.xscale('log')

plot_loghist(np.random.rand(200), 10)

【讨论】:

您应该在发布之前测试代码 - 因为函数声明后没有“:”,它无法编译。而且,添加后,代码仍然无法工作 - 它只会崩溃。 感谢您的指出。修正了错字。该代码在 python 3.5 上对我来说很好 对我也有用,python 3.8。感谢您的有用贡献【参考方案3】:

用 x 的对数绘制另一个直方图。

与在对数刻度上绘制 x 不同。绘制 x 的对数将是

np.log(x).plot.hist(bins=8)
plt.show()

不同之处在于 x 本身的值已被转换:我们正在查看它们的对数。

这与在对数刻度上绘制不同,在对数刻度上,我们保持 x 不变,但改变了水平轴的标记方式(向右挤压条形,向左拉伸条形)。

【讨论】:

以上是关于使用 Matplotlib 在对数尺度上绘制直方图的主要内容,如果未能解决你的问题,请参考以下文章

根据 Matplotlib 中的预计数数据绘制直方图

Matplotlib 绘制直方图、散点图

如何绘制直方图的密度而非计数? (Matplotlib)

numpy和matplotlib绘制直方图

matplotlib绘制直方图之基本配置——万能模板案例

matplotlib:直方图的绘制