如何在Pandas对数柱状图中提高Y轴刻度频率?
解决对数Y轴柱状图刻度显示频率不足的问题
你遇到的问题其实是因为对数坐标轴的LogLocator并不像线性轴的定位器那样直接响应numticks参数——它默认只显示10的整数幂次刻度(比如1e6、1e7),所以单纯设置numticks不会达到你想要的密集效果。下面给你两种可行的解决方案:
方案一:手动指定主刻度位置
如果你明确知道Y轴的数值范围,可以直接手动设置主刻度的位置,精准控制刻度数量:
# 获取Y轴数据的极值,确定对数范围 y_min = df['cycles'].min() y_max = df['cycles'].max() # 生成指定数量的对数刻度(这里设为10个,可按需调整) yticks = np.logspace(np.log10(y_min), np.log10(y_max), num=10) ax.set_yticks(yticks) # 用ScalarFormatter让刻度显示更友好(避免默认的科学计数法冗余) ax.get_yaxis().set_major_formatter(ticker.ScalarFormatter())
方案二:启用次要刻度并格式化
保留主刻度为10的幂次,同时启用每个数量级内的次要刻度(比如2×1e6、3×1e6…9×1e6),并让这些次要刻度显示标签,整体刻度会更密集:
# 配置主刻度为10的幂次 ax.yaxis.set_major_locator(ticker.LogLocator(base=10.0)) ax.yaxis.set_major_formatter(ticker.ScalarFormatter()) # 配置次要刻度,显示每个数量级内的2-9倍值 ax.yaxis.set_minor_locator(ticker.LogLocator(base=10.0, subs=np.arange(2,10)*0.1)) ax.yaxis.set_minor_formatter(ticker.ScalarFormatter()) # 调整次要刻度标签大小,避免和主刻度拥挤重叠 ax.tick_params(axis='y', which='minor', labelsize=8)
修改后的完整代码
把方案二整合到你的代码中,最终代码如下:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from matplotlib import rcParams import numpy as np import matplotlib.ticker as ticker df = pd.read_csv('exp-mediciones-grales-data.csv', sep=', ', engine='python') iteraciones = str(df.loc[0]["iteraciones_totales"]) + " iteraciones" # filtro datos filtro = [] tams = {128, 512, 1024, 2048} for i in range(0, len(df)): filtro.append(df.loc[i]["implementation"] not in {'asm-lu'} and df.loc[i]["width"] in tams) df = df[filtro] rcParams['figure.figsize'] = 12.0,6.0 # seteo tamaño en inches (default: 8.0, 6.0) ax = sns.barplot(x="width", y="cycles", hue="implementation", data=df) ax.set_xlabel("Width (#pxs)".decode('utf-8')) ax.set_ylabel("Cant. ciclos") ax.set_title(("Comparación ciclos totales - lena.bmp - escala log. - " + iteraciones).decode('utf-8')) ax.set_yscale('log') # --- 新增的刻度设置代码 --- # 配置主刻度 ax.yaxis.set_major_locator(ticker.LogLocator(base=10.0)) ax.yaxis.set_major_formatter(ticker.ScalarFormatter()) # 配置次要刻度,显示每个数量级内的2-9倍值 ax.yaxis.set_minor_locator(ticker.LogLocator(base=10.0, subs=np.arange(2,10)*0.1)) ax.yaxis.set_minor_formatter(ticker.ScalarFormatter()) # 调整次要刻度标签大小,避免拥挤 ax.tick_params(axis='y', which='minor', labelsize=8) # --- 新增结束 --- ax.grid(); plt.legend(loc='best') plt.savefig('img/comp-ciclos-gral.png') plt.show()
为什么原来的方法没用?
当你设置ax.set_yscale('log')后,Y轴的主定位器自动变成了LogLocator,它的numticks参数只是控制视图范围内最多显示的主刻度数量,但主刻度仍然只会落在10的幂次上,所以看起来刻度还是很稀疏。而上面的方案要么手动指定所有刻度,要么启用次要刻度并显示标签,就能有效提高刻度的显示频率。
内容的提问来源于stack exchange,提问作者jscherman
相关产品推荐
相关产品推荐

