Как пометить части общей суммы в matplotlib? - PullRequest
0 голосов
/ 04 марта 2020

Я пытаюсь создать простую гистограмму с помощью pypons 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 возможность легко достичь этого?

Спасибо за вашу помощь !

1 Ответ

0 голосов
/ 04 марта 2020

Чтобы получить значение x, соответствующее p% всех комментариев, просто отсортируйте список значений и затем индексируйте его на p% от общей длины. Вы можете добавить вертикальные линии в этих позициях и добавить вторую ось X, чтобы пометить их.

Чтобы получить значение x, соответствующее p% всех токенов, найдите, где находится элемент со значением 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 лотками:

resulting plot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...