如何在Python Plot中将图表数值显示为X.X Million格式
实现乘客量图表数值的X.X Million格式显示
我正在绘制年度乘客量图表,聚合数据为百万级,希望图表中的数值显示为X.X Million格式(例如将65,073,314,271显示为65.1 Million)。当前使用的代码如下:
现有数据处理代码
Pax_Major=MajorCarriers.groupby(by=["YEAR"])["PASSENGERS"].sum().reset_index().sort_values(["YEAR"])
现有绘图代码
fig, ax = plt.subplots(figsize=(13.33,7.5), dpi = 96) bar1=ax.bar(Pax_Major["YEAR"], Pax_Major["PASSENGERS"], width=0.6) ax.set_xlabel('', fontsize=12, labelpad=10) ax.xaxis.set_label_position("bottom") ax.xaxis.set_major_formatter(lambda s, i : f'{s:,.0f}') ax.xaxis.set_tick_params(pad=2, labelbottom=True, bottom=True, labelsize=12, labelrotation=0) labels = ["97", "98", "99", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22"] ax.set_xticks(Pax_Major['YEAR'], labels) ax.set_ylabel('Passengers per year', fontsize=12, labelpad=10) ax.yaxis.set_label_position("left") ax.yaxis.set_major_formatter(lambda s, i : f'{s:,.0f}') ax.yaxis.set_major_locator(MaxNLocator(integer=True)) ax.yaxis.set_tick_params(pad=2, labeltop=False, labelbottom=True, bottom=False, labelsize=12) ax.bar_label(bar1, labels=[f'{e:,.0f}' for e in Pax_Major['PASSENGERS']], padding=3, color='black', fontsize=8) colours = ["#bbdefb","#2196f3"] cmap = mpl.colors.LinearSegmentedColormap.from_list("colour_map", colours, N=256) norm = mpl.colors.Normalize(Pax_Major['PASSENGERS'].min(), Pax_Major['PASSENGERS'].max()) bar1 = ax.bar(Pax_Major['YEAR'], Pax_Major['PASSENGERS'], color=cmap(norm(Pax_Major['PASSENGERS'])), width=0.6, zorder=2)
当前图表显示完整大数,需修改为X.X Million格式。
解决方案
要实现X.X Million的显示格式,核心是将原始数值除以1000000后保留1位小数,再拼接"Million"后缀,需要修改y轴刻度格式化器和柱状图标签的逻辑:
1. 修改y轴刻度格式化器
替换原有的y轴格式化代码:
ax.yaxis.set_major_formatter(lambda s, i : f'{s/1000000:.1f} Million')
同时移除MaxNLocator的integer=True参数,因为数值已缩小到百万级,无需强制整数刻度:
ax.yaxis.set_major_locator(MaxNLocator())
2. 修改柱状图标签
替换原有的bar_label代码:
ax.bar_label(bar1, labels=[f'{e/1000000:.1f} Million' for e in Pax_Major['PASSENGERS']], padding=3, color='black', fontsize=8)
3. 完整修改后的绘图代码
import matplotlib.pyplot as plt from matplotlib.ticker import MaxNLocator import matplotlib as mpl fig, ax = plt.subplots(figsize=(13.33,7.5), dpi = 96) # 可选:提前计算百万级数据,减少重复计算 Pax_Major['PASSENGERS_MILLION'] = Pax_Major['PASSENGERS'] / 1000000 bar1=ax.bar(Pax_Major["YEAR"], Pax_Major["PASSENGERS"], width=0.6) ax.set_xlabel('', fontsize=12, labelpad=10) ax.xaxis.set_label_position("bottom") ax.xaxis.set_major_formatter(lambda s, i : f'{s:,.0f}') ax.xaxis.set_tick_params(pad=2, labelbottom=True, bottom=True, labelsize=12, labelrotation=0) labels = ["97", "98", "99", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22"] ax.set_xticks(Pax_Major['YEAR'], labels) # 可选:更新y轴标签说明单位 ax.set_ylabel('Passengers per year (Million)', fontsize=12, labelpad=10) ax.yaxis.set_label_position("left") ax.yaxis.set_major_formatter(lambda s, i : f'{s/1000000:.1f} Million') ax.yaxis.set_major_locator(MaxNLocator()) ax.yaxis.set_tick_params(pad=2, labeltop=False, labelbottom=True, bottom=False, labelsize=12) # 使用提前计算的百万级数据 ax.bar_label(bar1, labels=[f'{val:.1f} Million' for val in Pax_Major['PASSENGERS_MILLION']], padding=3, color='black', fontsize=8) colours = ["#bbdefb","#2196f3"] cmap = mpl.colors.LinearSegmentedColormap.from_list("colour_map", colours, N=256) norm = mpl.colors.Normalize(Pax_Major['PASSENGERS'].min(), Pax_Major['PASSENGERS'].max()) bar1 = ax.bar(Pax_Major['YEAR'], Pax_Major['PASSENGERS'], color=cmap(norm(Pax_Major['PASSENGERS'])), width=0.6, zorder=2) plt.show()
说明
- 若想调整小数位数,修改
.1f中的数字即可(比如.2f保留两位小数) - 提前计算
PASSENGERS_MILLION列可以避免重复除以1000000的计算,提升代码效率
内容的提问来源于stack exchange,提问作者Astrid T
相关产品推荐
相关产品推荐

