在Python中为Matplotlib直方图的x轴添加更多描述性标签

在Python中为Matplotlib直方图的x轴添加更多描述性标签,python,matplotlib,jupyter-notebook,histogram,distribution,Python,Matplotlib,Jupyter Notebook,Histogram,Distribution,我在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.

我在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文档中查找了这一点,但似乎找不到任何可以让我实现最终目标的东西


非常感谢您的帮助。

当您设置
bin=25
时,将在遇到的最低值和最高值之间设置25个等距的bin。如果您使用这些范围来标记垃圾箱,则可能会由于任意值而造成混乱。环绕这些垃圾箱边界似乎更合适,例如20的倍数。然后,这些值可以用作x轴上的记号标记,正好位于箱子之间

可以通过在条形图(矩形面片)中循环添加百分比。它们的高度表示属于该存储箱的行数,因此除以总行数并乘以100即可得出百分比。条形高度、x和半宽度可以定位文本

从matplotlib导入pyplot作为plt
将numpy作为np导入
作为pd进口熊猫
df=pd.DataFrame({'time_on_page':np.random.lognormal(4,1.1100)})
max_x=df['time_on_page'].max()
bin_width=max(20,np.四舍五入(max_x/25/20)*20)#四舍五入到20的倍数,使用max(20,…)避免四舍五入到零
箱柜=np.arange(0,最大箱柜宽度+箱柜宽度,箱柜宽度)
axes=df.hist(第页上的column='time',bin=bin,grid=False,figsize=(12,8),color='86bf91',rwidth=0.9)
ax=轴[0,0]
总计=长度(df)
ax.set_xticks(箱子)
对于ax.patches中的p:
h=p.获得高度()
如果h>0:
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_axis低于(真)
对于[‘左’、‘右’、‘上’]中的目录:
ax.spines[dir].set_可见(False)
最大刻度参数(轴=“y”,长度=0)#关闭y刻度
最大利润率(x=0.02)#更紧的x利润率
plt.show()

这就是你要找的吗?是的!这太棒了,约翰。感谢您抽出时间回答并提供指导。非常感谢。
bin\u width=max(10,np.四舍五入(max\u x/25/10)*10)
将四舍五入为10的倍数。
max(10,…
中的10只设置了一个最小值(以避免宽度为零)。除以25使
bin_宽度
约为总宽度的1/25。除以10,四舍五入,再乘以相同的值,结果四舍五入到10的倍数。注意,对于10的幂,这与
bin_宽度=max相同(10,np.四舍五入(max_x/25,-1))
其中
-1
表示在小数点后四舍五入到
-1
位。只需将所有百分比相加。如果一切正常,总和应为100(可能存在舍入错误,但如果正好有100行,则不会有任何舍入)。此外,在我的示例代码中,箱子的宽度为20,但您确实可以选择任何数字。如果唯一的目标是查看百分比,则您甚至不需要对箱子的宽度进行四舍五入(但刻度将更难读取)。对于整数值,您必须非常小心边界上的值。pandas hist的实现似乎将值90到99放在bin 90-100中,将值100放在bin 100-110中。您可以更改此行为,例如,将bin创建为
bins=np。arange(0.00001,…)
将90放在bin 80-90中,100放在bin 90-100中(但也会将0放入未显示的bin-10,0中)。