生成两个人口类别的plotly.express.bar图表+扩展到动画帧

问题描述 投票:0回答:1

我对Python、pandas 和plotly 都是新手。我正在做一个关于各个国家人口的个人项目,我想制作一个plotly.express + dash graph环境,但我一开始就遇到了麻烦。 :D

最初,我能够通过一些索引的旋转和重置来获得一个不错的表格,如下所示: 数据表

该表包含国家、性别(男性、女性,两者)和年份(1961-2019),然后是每个年龄范围的人口(5-9、10-14、...、总计)。我知道我可以用简单的代码行“提取”单个国家和年份:

country, year = "Andorra", 2019
df_country = df[ (df["geo"] == country) &  (df['TIME_PERIOD'] == year) ]

得到这样的东西: 按国家和年份过滤数据

然后我尝试根据上表获取 px.bar 图表,以便在同一张图表中为每个年龄范围获得两个水平条(男性、女性)。我写了以下代码:

px.bar(data_frame=df_country, x=df_country.loc[:, '<5':'75<'].columns, color='sex', height=300)

得到这个: 安道尔的奇怪统计数据?

因此,条形图按性别类别划分(第三个包括“男性+女性”),但不是在 y 轴上显示年龄范围,而是每个条形图被切成与表中的数值相对应的部分。

我有一种感觉,它必须对那些“宽”和“长”数据格式做一些事情,但我可能是错的。

我想从上表中得到的只是选择一个国家(例如安道尔),然后它在 y 轴上每个年龄范围显示两个条形(男性,女性)。像这样的东西: 单杠版本。

我还想以这样的方式包含安道尔数据框,以便我可以使用 TIME_PERIOD 列(基本上是年)来表示通常由

animation_frame
变量定义的漂亮滑块。

我想代码看起来像这样:

px.bar(data_frame=df_country, x=df_country.loc[:, '<5':'75<'], color='sex', animation_frame='TIME_PERIOD')

最终的想法是通过破折号选择国家/地区,但 px.bar 会生成这些“每个年龄范围的男性、女性”条形图,并且会有多年的滑块。我现在正在避免经典的人口金字塔。

提前致谢。

python pandas dataframe plotly-express
1个回答
0
投票

由于数据表示是图像,因此仅使用图像中可用的数据创建代码。女性和男性人口相同。如您所知,宽格式不兼容,因此我们将数据转换为长格式并创建图表。颜色编码是性别,y轴是年龄分组,x轴是人口,然后更改为分组。

import pandas as pd
import io

data = '''
id geo sex TIME_PER100 "<5" "5-9" "10-14" "15-19" "20-24" "25-29" "30-34" "35-39" "40-34" "45-49" "50-54" "55-59"
0 Andorra Female 1986 1099.0 1496.0 1704.0 1530.0 1993.0 2298.0 2016.0 1764.0 1319.0 1081.0 1024.0 1003.0
1 Andorra Female 1987 1153.0 1588.0 1759.0 1619.0 2153.0 2387.0 2190.0 1828.0 1472.0 1117.0 1079.0 1025.0
2 Andorra Female 1988 1129.0 1574.0 1772.0 1685.0 2057.0 2527.0 2257.0 1883.0 1565.0 1163.0 1117.0 1058.0
3 Andorra Female 1989 1099.0 1606.0 1795.0 1747.0 2070.0 2586.0 2406.0 1984.0 1690.0 1329.0 1120.0 1149.0
4 Andorra Female 1990 1182.0 1562.0 1712.0 1798.0 1997.0 2558.0 2417.0 2019.0 1759.0 1450.0 1135.0 1134.0
5 Andorra Male 1986 1099.0 1496.0 1704.0 1530.0 1993.0 2298.0 2016.0 1764.0 1319.0 1081.0 1024.0 1003.0
6 Andorra Male 1987 1153.0 1588.0 1759.0 1619.0 2153.0 2387.0 2190.0 1828.0 1472.0 1117.0 1079.0 1025.0
7 Andorra Male 1988 1129.0 1574.0 1772.0 1685.0 2057.0 2527.0 2257.0 1883.0 1565.0 1163.0 1117.0 1058.0
8 Andorra Male 1989 1099.0 1606.0 1795.0 1747.0 2070.0 2586.0 2406.0 1984.0 1690.0 1329.0 1120.0 1149.0
9 Andorra Male 1990 1182.0 1562.0 1712.0 1798.0 1997.0 2558.0 2417.0 2019.0 1759.0 1450.0 1135.0 1134.0
'''

df = pd.read_csv(io.StringIO(data), delim_whitespace=True, index_col=0)

# wide to long
df_long = df.melt(id_vars=['geo','sex','TIME_PER100'], value_vars=df.columns[3:], var_name='age', value_name='poplation')

df_long.head()
    geo sex TIME_PER100 age poplation
0   Andorra Female  1986    <5  1099.0
1   Andorra Female  1987    <5  1153.0
2   Andorra Female  1988    <5  1129.0
3   Andorra Female  1989    <5  1099.0
4   Andorra Female  1990    <5  1182.0

import plotly.express as px

fig = px.bar(df_long, x="poplation", y="age", orientation='h', color='sex', animation_frame='TIME_PER100')
fig.update_layout(barmode='group')

fig.show()

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.