央视都在用的“南丁格尔玫瑰图”,原来Python也可以画

前一阵子,我看到央视新闻中,有一张比较好看数据图,如下:

央视都在用的“南丁格尔玫瑰图”,原来Python也可以画

后来才知道这叫“南丁格尔玫瑰图”,是南丁格尔护士在克里米亚战争期间提交的一份关于士兵死伤报告时发明的一种图表。

我心想能不能用Python也画一个,就去网上搜了一些资料,然后自己捣鼓了一下代码,并进行了梳理,下面是具体步骤。


第一步:安装并导入相关包

主要用到了pandas和pyecharts这两个包,需要注意的是pyecharts不同版本之间的的代码可能稍有不同,我这里安装的最新版,也就是1.7.1

<code>pip install pandas
pip install pyecharts/<code>

安装完成后导入:

<code>import pandas as pd
from pyecharts.charts import Pie
from pyecharts import options as opts/<code>


第二步:读取数据

我数据放在Excel中,内容与上文央视新闻的数据一样,是3月11日前最后一次确诊新冠肺炎病例连续零新增的天数,共计25个省市区,如下:

央视都在用的“南丁格尔玫瑰图”,原来Python也可以画

data.xlsx

用pandas读取数据:

<code>data = pd.read_excel('data.xlsx')
data.sort_values(by='天数', ascending=False, inplace=True)
province = data['省区市'].values.tolist()
days = data['天数'].values.tolist()/<code>

其中第二行代码的作用是将数据降序排列,如果各位事先在Excel中排好序了,就没必要写第二行代码。

之所以要降序,是因为最后生成的图的数据顺序,与原数据顺序是一致的,降序后画出来的南丁格尔玫瑰图更加直观。


第三步:设置颜色序列

南丁格尔玫瑰图是否好看与其颜色十分相关,我们要事先给定每个数据想呈现的颜色,并且尽量让它们过渡的自然些。

<code>color_series = ['#faeb23', '#e8e517', '#c9db33', '#9fcb3d', '#6bbe45',
                '#37b64b', '#3db979', '#11adcf', '#1f9bca', '#1d8fc6',
                '#2d6da4', '#26539e', '#2a3780', '#423787', '#69398d',
                '#7d3a93', '#913986', '#cf208f', '#ea257e', '#eb2462',
                '#ee3131', '#f1562f', '#f67932', '#f89230', '#e2a924']/<code>


第四步:实例化Pie类

因为主要用到了pyecharts中Pie这个类,所以要先实例化它:

<code>pie = Pie(init_opts=opts.InitOpts(width='1350px', height='900px'))
pie.set_colors(color_series)
pie.add("", [z for z in zip(province, days)],
         radius=["30%", "120%"],
         center=["50%", "66%"],
         rosetype="area")/<code> 
  • radius:半径大小,数组的第一项是内半径,第二项是外半径,默认为 [0, 75],如果写百分比就是宽高的尺寸乘以百分比
  • center:中心坐标,数组的第一项是横坐标,第二项是纵坐标,默认为 [50, 50]
  • rosetype:使用南丁格尔玫瑰图,并选用模式,有radius和area两种模式。默认为radius。radius:扇区圆心角展现数据的百分比,半径展现数据的大小;area:所有扇区圆心角相同,仅通过半径展现数据大小。


第五步:设置全局配置

<code>pie.set_global_opts(title_opts=opts.TitleOpts(title='多个省区市\n确诊病例连续多日', subtitle='零新增',
                                               title_textstyle_opts=opts.TextStyleOpts(font_size=32, color='#0c2a46', font_family="KaiTi", font_weight="bold"),
                                               subtitle_textstyle_opts=opts.TextStyleOpts(font_size=66, color='#0c2a46', font_family="KaiTi", font_weight="bold"),
                                               pos_right='center', pos_left='center', pos_top='58%', pos_bottom='center'),
                     legend_opts=opts.LegendOpts(is_show=True),
                     toolbox_opts=opts.ToolboxOpts(pos_top='5%'))/<code>
  • title_opts:主副标题的样式设置,这里面的内容看上去比较多,其实大家自己试一下就知道了,类似于CSS,对标题的大小、颜色、字体、是否加粗、位置信息进行设置。
  • legend_opts:是否显示图例。
  • toolbox_opts:显示工具盒,并对其显示的位置进行设置。

这里不知道图例和工具盒是啥也没关系,等看到本文最后生成的图就知道啦。


第六步:设置系列配置项

<code>pie.set_series_opts(label_opts=opts.LabelOpts(is_show=True, position="inside", font_size=16,
                                               formatter="{b}\n{c}天", font_style="normal",
                                               font_weight="bold", font_family="SimHei"))/<code>

这些参数看上去复杂,其实就是对每个扇形里面的文字样式进行设置,就不解释了。


第七步:生成html文件

<code>pie.render('南丁格尔玫瑰图.html')/<code>

将上面的代码运行后,就会生成一个html文件,打开后如下:

央视都在用的“南丁格尔玫瑰图”,原来Python也可以画

南丁格尔玫瑰图.html

其中最上面的就是图例,点击一下可以隐藏/显示相应的区域,右上方的就是工具盒,至于工具盒里面的功能嘛,就请大家自行摸索啦。


最后我猜很多人,肯定会奇怪为什么要选用南丁格尔玫瑰图,明明传统的饼状图或者柱状图等都能对数据进行展示,我想这正是当年南丁格尔护士思考的问题,因为在她眼里,每一个数字都代表了一个生命,要尽量体现出每一点的细微差别,所以从视觉的角度来看,南丁格尔玫瑰图通过增加半径这个维度信息,放大了不同数据之间的差别,这样即便只相差一个值,也能被察觉到。

或许在医护人员心中,不存在死亡100个人这样的说法,只存在一个生命逝去这件事,发生了100遍...


关注微信公众号“Python小镇”,发现更多干货知识!


分享到:


相關文章: