Добавьте более описательную маркировку на ось x гистограммы Matplotlib в Python - PullRequest
1 голос
/ 03 августа 2020

Я создал гистограмму в блокноте Jupyter, чтобы показать распределение времени на странице в секундах для 100 посещений сети.

Код следующий:

ax = df.hist(column='time_on_page', bins=25, grid=False, figsize=(12,8), color='#86bf91', zorder=2, rwidth=0.9)

ax = ax[0]
for x in ax:

    # Despine
    x.spines['right'].set_visible(False)
    x.spines['top'].set_visible(False)
    x.spines['left'].set_visible(False)

    # Switch off ticks
    x.tick_params(axis="both", which="both", bottom="off", top="off", labelbottom="on", left="off", right="off", labelleft="on")

    
    # Draw horizontal axis lines
    vals = x.get_yticks()
    for tick in vals:
        x.axhline(y=tick, linestyle='dashed', alpha=0.4, color='#eeeeee', zorder=1)

    # Set title
    x.set_title("Time on Page Histogram", fontsize=20, weight='bold', size=12)

    # Set x-axis label
    x.set_xlabel("Time on Page Duration (Seconds)", labelpad=20, weight='bold', size=12)

    # Set y-axis label
    x.set_ylabel("Page Views", labelpad=20, weight='bold', size=12)

    # Format y-axis label
    x.yaxis.set_major_formatter(StrMethodFormatter('{x:,g}'))

Это дает следующее визуализация:

введите описание изображения здесь

Я в целом доволен внешним видом, однако я бы хотел, чтобы ось была немного более описательной, возможно, показывала диапазон ячеек для каждой ячейки и процент от общей суммы, которую составляет каждая ячейка .

Искали это в документации Matplotlib, но, похоже, не нашли ничего, что позволило бы мне достичь моей конечной цели.

Любая помощь очень ценится.

1 Ответ

2 голосов
/ 03 августа 2020

Когда вы устанавливаете bins=25, между наименьшим и наибольшим встречающимися значениями устанавливается 25 одинаковых интервалов. Если вы используете эти диапазоны для маркировки ящиков, это может сбить с толку из-за произвольных значений. Кажется более подходящим округлить эти границы ячеек, например, кратно 20. Затем эти значения можно использовать как отметки на оси X, удобно между ячейками.

Проценты могут быть добавлены с помощью петля через бруски (прямоугольник angular патчей). Их высота указывает количество строк, принадлежащих корзине, поэтому деление на общее количество строк и умножение на 100 дает процент. Высота, x и половина ширины полосы могут позиционировать текст.

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

df = pd.DataFrame({'time_on_page': np.random.lognormal(4, 1.1, 100)})
max_x = df['time_on_page'].max()
bin_width = max(20, np.round(max_x / 25 / 20) * 20) # round to multiple of 20, use max(20, ...) to avoid rounding to zero
bins = np.arange(0, max_x + bin_width, bin_width)
axes = df.hist(column='time_on_page', bins=bins, grid=False, figsize=(12, 8), color='#86bf91', rwidth=0.9)
ax = axes[0, 0]
total = len(df)
ax.set_xticks(bins)
for p in ax.patches:
    h = p.get_height()
    if h > 0:
        ax.text(p.get_x() + p.get_width() / 2, h, f'{h / total * 100.0  :.0f} %\n', ha='center', va='center')
ax.grid(True, axis='y', ls=':', alpha=0.4)
ax.set_axisbelow(True)
for dir in ['left', 'right', 'top']:
    ax.spines[dir].set_visible(False)
ax.tick_params(axis="y", length=0)  # Switch off y ticks
ax.margins(x=0.02) # tighter x margins
plt.show()

пример сюжета

...