请求:用Python绘制字符串变量的频率/百分比柱状图(非重复问题)
问题说明
我要在Python中复现字符串变量的百分比柱状图,用Stata可以实现,但Python代码运行失败。
我的问题并非以下问题的重复:Given a pandas Series that represents frequencies of a value, how can I turn those frequencies into percentages?,因为我需要的是绘图而非频率表,该问题被错误归类。
Stata实现代码及效果
Stata代码:
clear all input str10 Genero "Mujer" "Mujer" "Hombre" "Hombre" "Hombre" end graph bar (percent), over(Genero)
绘图效果为:展示Mujer占40%、Hombre占60%的百分比柱状图。
我的Python代码(运行失败)
import numpy as np import os import seaborn as sns import pandas as pd import matplotlib.pyplot as plt os.chdir("C:/Users/Desktop") import matplotlib.ticker as mtick df = pd.DataFrame({'Genero': ['Mujer','Mujer','Hombre','Hombre','Hombre']}) print(df) axx = df.plot.bar(x='Genero') axx.yaxis.set_major_formatter(mtick.PercentFormatter()) plt.savefig('myfilename.png')
解决方案
原代码失效的核心原因是:直接对原始DataFrame调用plot.bar()会将每一行数据单独绘制成柱子,而非先统计各分类的频率再转换为百分比。以下是两种可行的实现方式:
方法一:先统计频率与百分比,再绘图
先对目标列做频率统计,计算每个类别占总数的百分比,再基于统计结果绘图:
import pandas as pd import matplotlib.pyplot as plt import matplotlib.ticker as mtick df = pd.DataFrame({'Genero': ['Mujer','Mujer','Hombre','Hombre','Hombre']}) # 统计类别频率并转换为百分比 percent_stats = df['Genero'].value_counts(normalize=True).mul(100).reset_index() percent_stats.columns = ['Genero', '百分比'] # 绘制柱状图 ax = percent_stats.plot.bar(x='Genero', y='百分比', legend=False) # 设置y轴为百分比格式 ax.yaxis.set_major_formatter(mtick.PercentFormatter()) # 为每个柱子添加百分比标签 for patch in ax.patches: height = patch.get_height() ax.text(patch.get_x() + patch.get_width()/2., height, f'{height:.0f}%', ha='center', va='bottom') plt.title('Genero 百分比分布') plt.savefig('myfilename.png') plt.show()
方法二:使用Seaborn直接绘制百分比柱状图
借助Seaborn的countplot快速统计频次,再自定义添加百分比标签,代码更简洁:
import seaborn as sns import pandas as pd import matplotlib.pyplot as plt import matplotlib.ticker as mtick df = pd.DataFrame({'Genero': ['Mujer','Mujer','Hombre','Hombre','Hombre']}) plt.figure(figsize=(8,5)) ax = sns.countplot(x='Genero', data=df) total_count = len(df) # 为每个柱子添加百分比标签 for patch in ax.patches: percentage = f'{100 * patch.get_height()/total_count:.0f}%' x_pos = patch.get_x() + patch.get_width() / 2 y_pos = patch.get_height() ax.annotate(percentage, (x_pos, y_pos), ha='center', va='bottom') # 设置y轴为百分比格式 ax.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=total_count)) plt.title('Genero 百分比分布') plt.savefig('myfilename.png') plt.show()
内容的提问来源于stack exchange,提问作者Rodrigo Badilla
相关产品推荐
相关产品推荐

