You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Plotly Express双类别条形图绘制及动画扩展问题求助

解决方案:Plotly Express + Dash 分性别年龄段人口可视化

核心问题:数据格式转换

你的判断完全正确,问题根源在宽数据格式。当前表格中<5到75<这类年龄段是独立列,Plotly无法识别它们属于同一类别(年龄段)的不同取值,因此才会把列名当作x轴的分割维度。必须先将数据转换为长格式:

1. 数据重塑(宽转长)

使用pd.melt将所有年龄段列合并为两列:年龄段(存储<5/5-9等标签)和人口数(对应数值),同时保留geo(国家)、TIME_PERIOD(年份)、sex(性别)作为维度标识:

import pandas as pd

# 定义需要转换的年龄段列范围
age_cols = df.loc[:, '<5':'75<'].columns

# 宽格式转长格式
df_long = pd.melt(
    df,
    id_vars=['geo', 'TIME_PERIOD', 'sex'],  # 保留的维度列
    value_vars=age_cols,  # 需要转为行数据的列
    var_name='年龄段',  # 新列:存储年龄段标签
    value_name='人口数'  # 新列:存储对应人口数值
)

2. 绘制带年份动画的水平条形图

转成长格式后,即可生成符合需求的可视化:每个年龄段对应男/女两个并列水平条形,同时添加年份动画滑块:

import plotly.express as px

# 生成水平条形图
fig = px.bar(
    df_long,
    y='年龄段',  # 年龄段放置在y轴
    x='人口数',  # 人口数放置在x轴
    color='sex',  # 按性别区分条形颜色
    barmode='group',  # 启用并列条形模式(非堆叠)
    animation_frame='TIME_PERIOD',  # 基于年份生成动画滑块
    height=600,
    title='分性别年龄段人口分布',
    labels={'TIME_PERIOD': '年份'}  # 优化动画滑块的显示标签
)

# 调整布局,提升可读性
fig.update_layout(
    xaxis_title='人口数',
    yaxis_title='年龄段',
    yaxis={'categoryorder': 'total ascending'}  # 按人口总数排序年龄段(可选)
)

fig.show()

3. 适配Dash的国家选择功能

整合Dash组件,添加国家下拉选择框,通过回调实现图表的动态更新:

from dash import Dash, dcc, html, Input, Output, callback

# 初始化Dash应用
app = Dash(__name__)

# 生成国家下拉选项列表
country_options = [{'label': c, 'value': c} for c in df_long['geo'].unique()]

# 应用布局
app.layout = html.Div([
    html.H1('国家人口年龄性别分布可视化'),
    # 国家选择下拉框
    dcc.Dropdown(
        id='country-select',
        options=country_options,
        value='Andorra',  # 默认选中安道尔
        clearable=False
    ),
    # 图表容器
    dcc.Graph(id='population-bar-chart')
])

# 回调函数:根据选中国家更新图表
@callback(
    Output('population-bar-chart', 'figure'),
    Input('country-select', 'value')
)
def update_chart(selected_country):
    # 筛选选中国家的数据
    filtered_df = df_long[df_long['geo'] == selected_country]
    
    # 生成更新后的图表
    fig = px.bar(
        filtered_df,
        y='年龄段',
        x='人口数',
        color='sex',
        barmode='group',
        animation_frame='TIME_PERIOD',
        height=600,
        title=f'{selected_country} 分性别年龄段人口分布',
        labels={'TIME_PERIOD': '年份'}
    )
    
    fig.update_layout(
        xaxis_title='人口数',
        yaxis_title='年龄段',
        yaxis={'categoryorder': 'total ascending'}
    )
    
    return fig

# 运行应用
if __name__ == '__main__':
    app.run_server(debug=True)

关键细节说明

  • barmode='group'是实现并列条形的核心参数,确保同一年龄段下的男/女条形并排显示而非堆叠。
  • animation_frame='TIME_PERIOD'会自动生成年份切换控件,支持播放、暂停及手动切换年份。
  • Dash回调通过Input获取选中的国家,Output返回更新后的图表,实现无刷新的动态交互。

内容的提问来源于stack exchange,提问作者Demenaio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 11:17:18