如何在Pandas多饼图中显示实际数值而非百分比?
修正Matplotlib多饼图中显示绝对值的问题
我明白你遇到的困扰:单个饼图用autopct显示绝对值没问题,但当用subplots=True创建多个饼图时,原来的方法就失效了。问题出在你定义的absolute_value函数上——它直接引用了整个DataFrame的values,而每个子饼图对应DataFrame的单独一列,各自有不同的总和,所以计算出来的绝对值完全不对。
问题根源
你的absolute_value函数里,val/100.*df.values会把当前饼块的百分比乘以整个DataFrame的所有数据,而不是当前子图对应列的总和。比如"Total"列的总和是825+725=1550,"Last 2 Month"列的总和是56+73=129,每个饼图需要用自己的总和来计算绝对值,而不是共享整个DataFrame的数据。
修正方案
这里有两种简洁的修正方式,你可以根据自己的习惯选择:
方式一:在df.plot.pie中绑定每列的总和
我们可以通过lambda函数给autopct传递当前子图对应列的总和,让绝对值计算更精准:
import pandas as pd import numpy as np import matplotlib.pyplot as plt d = {'Yes':pd.Series([825, 56], index=["Total", "Last 2 Month"]), 'No':pd.Series([725, 73], index=["Total", "Last 2 Month"])} df = pd.DataFrame(d) df = df.T def absolute_value(val, total): # 用当前饼图的总和计算绝对值,保留整数 return f'{np.round(val / 100 * total, 0):.0f}' # 遍历每个列,给autopct绑定对应列的总和 axes = df.plot.pie( subplots=True, figsize=(12, 6), autopct=[lambda val, total=df[col].sum(): absolute_value(val, total) for col in df.columns] ) plt.tight_layout() plt.show()
方式二:手动创建子图逐个绘制(更直观)
如果你想更清晰地控制每个饼图的细节,可以手动创建子图,然后为每个子图单独计算总和并绘制:
import pandas as pd import numpy as np import matplotlib.pyplot as plt d = {'Yes':pd.Series([825, 56], index=["Total", "Last 2 Month"]), 'No':pd.Series([725, 73], index=["Total", "Last 2 Month"])} df = pd.DataFrame(d) df = df.T # 创建1行2列的子图 fig, axes = plt.subplots(1, 2, figsize=(12, 6)) # 遍历每个子图和对应的列 for ax, col_name in zip(axes, df.columns): # 获取当前列的数据 current_data = df[col_name] # 计算当前饼图的总和 total = current_data.sum() # 绘制饼图,autopct用当前总和计算绝对值 ax.pie( current_data, labels=current_data.index, autopct=lambda val, t=total: f'{np.round(val / 100 * t, 0):.0f}' ) # 给子图添加标题 ax.set_title(col_name) plt.tight_layout() plt.show()
这两种方式都能让每个饼图正确显示对应的绝对值,而不是错误的整体数据计算结果。
内容的提问来源于stack exchange,提问作者yigitozmen
相关产品推荐
相关产品推荐

