如何修改柱状图宽度同时保持所有柱子间距均匀
问题:Pandas设置width后柱状图首尾柱子间距过大
我尝试用Pandas制作所有柱子间距均匀的柱状图。不指定width参数时,默认效果符合预期;但指定width参数后,图表左右边距未改变,导致首尾柱子的间距大于其他柱子。尝试用ax.margins(x=0)调整边距,但无效果。如何保持所有柱子的间距均匀?
import pandas as pd import numpy as np import matplotlib import matplotlib.pyplot as plt matplotlib.use('TkAgg') print(matplotlib.__version__) # 3.5.3 print(pd.__version__) # 1.3.5 def grid_in_between(ax): """使用次要网格线在(主)数据轴值之间创建网格线 参数: ax: Matplotlib坐标轴 """ ticks = ax.get_xticks() ax.set_xticks(np.array(ticks[:-1]) + np.diff(ticks) / 2, minor=True) ax.grid(visible=True, axis='x', which='minor') ax.grid(visible=False, axis='x', which='major') ax.tick_params(which='minor', length=0, axis='x') df = pd.DataFrame({'value': range(8)}) fig, ax = plt.subplots(1, 2) df.plot.bar(ax=ax[0]) df.plot.bar(ax=ax[1], width=.95) grid_in_between(ax[0]) grid_in_between(ax[1]) ax[0].set_title('间距均匀') ax[1].set_title('设置width参数\n导致首尾间距过大') ax[1].margins(x=0) # 无效果 plt.show()

解决方法
问题核心是Pandas的plot.bar()默认给分类x轴预留固定边距,ax.margins(x=0)对分类轴不生效。可以通过手动调整x轴范围,让首尾柱子的边缘贴合x轴边界,从而保证所有柱子间距一致。
修改后的完整代码
import pandas as pd import numpy as np import matplotlib import matplotlib.pyplot as plt matplotlib.use('TkAgg') print(matplotlib.__version__) # 3.5.3 print(pd.__version__) # 1.3.5 def grid_in_between(ax): """使用次要网格线在(主)数据轴值之间创建网格线 参数: ax: Matplotlib坐标轴 """ ticks = ax.get_xticks() ax.set_xticks(np.array(ticks[:-1]) + np.diff(ticks) / 2, minor=True) ax.grid(visible=True, axis='x', which='minor') ax.grid(visible=False, axis='x', which='major') ax.tick_params(which='minor', length=0, axis='x') df = pd.DataFrame({'value': range(8)}) fig, ax = plt.subplots(1, 2) df.plot.bar(ax=ax[0]) df.plot.bar(ax=ax[1], width=.95) # 关键:调整x轴范围,让首尾柱子对齐边界 bar_width = 0.95 x_ticks = ax[1].get_xticks() ax[1].set_xlim(x_ticks[0] - bar_width/2, x_ticks[-1] + bar_width/2) grid_in_between(ax[0]) grid_in_between(ax[1]) ax[0].set_title('间距均匀') ax[1].set_title('设置width参数\n间距保持均匀') plt.show()
原理说明
分类柱状图的每个柱子中心对应x轴刻度位置,柱子宽度由width控制。默认x轴范围是[第一个刻度-0.5, 最后一个刻度+0.5],当width小于1时,柱子和边界间会留出空隙,导致首尾间距偏大。通过将x轴范围调整为[第一个刻度 - width/2, 最后一个刻度 + width/2],能让首尾柱子的边缘刚好贴合x轴边界,所有柱子的左右间距就会保持一致。
内容的提问来源于stack exchange,提问作者Wouter
相关产品推荐
相关产品推荐

