生成top图_Python 绘制柱形竞赛图

6e4e55a3203a52da5fc17ee8deacc7e7.png

柱形竞赛图(Bar Chart Race)是一种动态的柱形图,它能非常直观地反应随着时间流逝数据的变化。下图是最终效果。

2168957c3c6f3685317ed370d785ef62.png
COVID-19 Confirms by Countryhttps://www.zhihu.com/video/1244644470194688000

那么如何绘制呢?今天介绍一个开源库,就叫 bar_chart_race,使用这个库制作柱形竞赛图可以说非常简单了。

安装

安装 bar_chart_race 只需要通过 pip:

pip install bar_chart_race

bar_chart_race 使用 ffmpeg 生成 mp4 文件展示。所以还需要安装 ffmpeg:

conda install -c conda-forge ffmpeg

本示例使用 Mars 来预处理数据。安装 Mars 通过:

pip install pymars

准备数据

今天我们要绘制的是新冠确诊人数前十的国家的数据变化。我们使用数据集:地址,点击链接下载 CSV 文件。

In [1]: import mars.dataframe as md                                                                                                                                                                         

In [2]: df = md.read_csv('countries-aggregated.csv')[['Date', 'Country', 'Confirmed']]                                                                                                                      

In [3]: df.execute()                                                                                                                                                                                        
Out[3]: 
             Date             Country  Confirmed
0      2020-01-22         Afghanistan          0
1      2020-01-22             Albania          0
2      2020-01-22             Algeria          0
3      2020-01-22             Andorra          0
4      2020-01-22              Angola          0
...           ...                 ...        ...
21239  2020-05-13  West Bank and Gaza        375
21240  2020-05-13      Western Sahara          6
21241  2020-05-13               Yemen         70
21242  2020-05-13              Zambia        446
21243  2020-05-13            Zimbabwe         37

接着我们确定柱状图上要显示哪些国家,这里我们计算出历史上总确诊人数排前十的国家显示。

In [4]: top_10 = df.groupby('Country').agg({'Confirmed': 'sum'}).sort_values(by='Confirmed', ascending=False)[:10]                                                                                          

In [5]: top_10.execute()                                                                                                                                                                                    
Out[5]: 
                Confirmed
Country                  
US               36901733
Italy             8940009
Spain             8862792
China             7778728
Germany           6730778
France            6391282
United Kingdom    5887815
Iran              4127613
Turkey            3888111
Russia            3450701

有了前10的国家,接着我们就需要从原始数据里过滤出来这些国家的数据。

In [6]: data_in_top_10 = df[df.Country.isin(top_10.index)]                                                                                                                                                  

In [7]: data_in_top_10.execute()                                                                                                                                                                            
Out[7]: 
             Date         Country  Confirmed
36     2020-01-22           China        548
62     2020-01-22          France          0
66     2020-01-22         Germany          0
81     2020-01-22            Iran          0
85     2020-01-22           Italy          0
...           ...             ...        ...
21196  2020-05-13          Russia     242271
21214  2020-05-13           Spain     228691
21229  2020-05-13          Turkey     143114
21230  2020-05-13              US    1390406
21234  2020-05-13  United Kingdom     230985

[1130 rows x 3 columns]

要绘图,bar_chart_race 接受一个横表,索引是时间,列标签是国家,里面的值就是每天的人数了。要做到这个效果只需要调用 DataFrame.pivot做个列转行的操作即可,可惜 Mars 暂时还不支持 pivot,所以我们先转 pandas。

In [8]: # Mars 0.4 版本前(含 0.4.0rc1)通过 data_in_top_10.execute() 转成 pandas DataFrame 
   ...: # 0.4 之后通过 to_pandas() 转 
   ...: pivot_df = data_in_top_10.to_pandas().pivot(index='Date', columns='Country', values='Confirmed')                                                                                                    

In [9]: pivot_df                                                                                                                                                                                            
Out[9]: 
Country     China  France  Germany    Iran  ...   Spain  Turkey       US  United Kingdom
Date                                        ...                                         
2020-01-22    548       0        0       0  ...       0       0        1               0
2020-01-23    643       0        0       0  ...       0       0        1               0
2020-01-24    920       2        0       0  ...       0       0        2               0
2020-01-25   1406       3        0       0  ...       0       0        2               0
2020-01-26   2075       3        0       0  ...       0       0        5               0
...           ...     ...      ...     ...  ...     ...     ...      ...             ...
2020-05-09  83990  176782   171324  106220  ...  223578  137115  1309550          216525
2020-05-10  84010  177094   171879  107603  ...  224350  138657  1329260          220449
2020-05-11  84011  177547   172576  109286  ...  227436  139771  1347881          224332
2020-05-12  84018  178349   173171  110767  ...  228030  141475  1369376          227741
2020-05-13  84024  178184   174098  112725  ...  228691  143114  1390406          230985

[113 rows x 10 columns]

绘图

有了能用的数据,我们就正式开始绘图了。

In [10]: import bar_chart_race as bcr
Out[10]: bcr_html = bcr.bar_chart_race(df=pivot_df, filename=None,
                                       steps_per_period=10, period_length=300,
                                       title='COVID-19 Confirms by Country')

在 jupyter 里,可以直接显示竞争图。

In [11]: from IPython.display import HTML
Out[11]: HTML(bcr_html)
2168957c3c6f3685317ed370d785ef62.png
COVID-19 Confirms by Countryhttps://www.zhihu.com/video/1244646430906232832

参考

Bar Chart Race:https://github.com/dexplo/bar_chart_race

Mars:https://github.com/mars-project/mars

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值