我正在尝试使用pythons matplotlib创建一个简单的直方图。
这是关于评论长度的分布。我有数千条评论,而且我已经有以下代码:
x = [60, 55, 2, 30, ..., 190]
plt.hist(x, bins=100)
plt.xlim(0,150)
plt.grid(axis="x")
plt.title("Distribution of Comment Lengths")
plt.xlabel("Tokens/Comment")
plt.ylabel("Amount of Comments")
plt.show()
[我想实现的一种方法是显示到哪一点我已经通过了所有代币的50%(或33%和66%,或25%,50%和75%)。我正在想象一条垂直线,将分布分为两半,两边的令牌数量相等。
matplotlib是否有机会轻松实现这一目标?
感谢您的帮助!
要获得与所有注释的p%
相对应的x值,只需对值列表进行排序,然后将其索引为总长度的p%
。您可以在这些位置添加垂直线,并添加第二个x轴来标记它们。
要获取与所有标记的p%
相对应的x值,请找到具有p% of the sum of all the x's
值的元素在数组中的位置,其中包含已排序列表的累积和。使用该位置来索引值的排序列表。
这里有一些代码显示了它如何工作。
from matplotlib import pyplot as plt
import numpy as np
# create some random data to test, convert to a regular Python list to be similar to the question
x = list(np.abs(np.random.normal(85, 30, 2000)))
wanted_percentiles = [5, 10, 25, 33, 50, 66, 75, 90, 95]
sx = np.array(x)
sx.sort()
cx = sx.cumsum()
percentile_sx = [sx[int(len(x) * p / 100)] for p in wanted_percentiles]
percentile_cx = [sx[cx.searchsorted(cx[-1] * p / 100)] for p in wanted_percentiles]
fig, axes = plt.subplots(ncols=2, figsize=(12, 4))
for ax, percentile, color, title in zip(axes, [percentile_sx, percentile_cx],
['crimson', 'limegreen'], ['Comments Percentile', 'Tokens Percentile']):
ax.hist(x, bins=20)
for xp in percentile:
ax.axvline(xp, color=color)
ax2 = ax.twiny()
ax.set_xlim(0, 150)
ax2.set_xlim(ax.get_xlim()) # both axes need exactly the same limits
ax2.set_xticks(percentile) # use the xs corresponding to the percentiles as tick positions
ax2.set_xticklabels(wanted_percentiles, color=color) # use the percentiles to label the ticks
ax.set_title("Distr. of Comment Lengths, " + title)
ax.set_xlabel("Comments binned via number of tokens")
ax.set_ylabel("Amount of Comments")
plt.show()
在左侧有100箱的地块,在右侧有20箱的样子: