如何使用Plotly绘制正确的人口金字塔图
错误原因
- 未对数据按性别、年龄分组聚合,直接把全量count列同时赋值给男女两个分组
- 男性条形的x值未取负数,无法展示在x轴左半侧
- 年龄列是字符串格式,y轴未按年龄大小排序
修改后代码
import plotly.graph_objs as go import plotly.offline as pyo import pandas as pd df = pd.DataFrame({ 'age': ['11', '19', '22', '30', '24', '27', '15'], 'group': ['A', 'B', 'C', 'C', 'B', 'C', 'B'], 'gender': ['Male','Female','Male','Female','Female','Male','Male'], 'count':[3,5,6,1,4,5,2] }) # 先把年龄转数值,排序后再转回字符串保证y轴顺序正确 df['age'] = df['age'].astype(int) df = df.sort_values('age') df['age'] = df['age'].astype(str) # 分别提取男女的计数,按年龄对齐 men_bins = df[df['gender'] == 'Male']['count'].apply(lambda x: -x) women_bins = df[df['gender'] == 'Female']['count'] y = df['age'].unique() layout = go.Layout(yaxis=go.layout.YAxis(title='年龄'), xaxis=go.layout.XAxis( range=[-df['count'].max(), df['count'].max()], title='人数', # 把负半轴的标签显示为正数,更符合阅读习惯 tickvals=[-6, -4, -2, 0, 2, 4, 6], ticktext=['6', '4', '2', '0', '2', '4', '6'] ), barmode='relative', bargap=0.1) data = [go.Bar(y=y, x=men_bins, orientation='h', name='男性', hoverinfo='x', # 悬浮提示显示正数 hovertemplate='%{x*-f}', marker=dict(color='powderblue') ), go.Bar(y=y, x=women_bins, orientation='h', name='女性', hoverinfo='text', marker=dict(color='seagreen') )] pyo.iplot(dict(data=data, layout=layout))
优化说明
- 对年龄列做了数值转换和排序,保证y轴按年龄大小有序展示
- 对男性计数取负,实现左右两侧分开展示的金字塔效果
- 调整了x轴刻度标签,把负半轴的数值显示为正数,更符合人口金字塔的阅读习惯
- 调整悬浮提示的男性计数显示为正数,避免负数带来的误解
内容的提问来源于stack exchange,提问作者snow
相关产品推荐
相关产品推荐

