本课将继续学习其他类型的统计图,有了上一课的基础,学习下面的内容就比较容易了。不同类型的统计图,只是生成 Trace 对象的类的名称变化一下,其参数的调用方式大同小异。因此,当本课介绍几种统计图时,可能就不如以往那么细致,如果读者想要详细了解某些细节,就需要亲自阅读文档——这种方法是必须要掌握的。
4.3.1 饼图
继续使用上一课的数据集。
import pandas as pd
import plotly as py
import plotly.graph_objs as go
py.offline.init_notebook_mode(connected=True)
df = pd.read_csv("/Users/qiwsir/Documents/Codes/DataSet/universityrank/timesData.csv")
用饼图统计入榜的中国大学 Top5。
dfcn = df[df['country']=='China']
dfcn5 = dfcn.iloc[:5, :]
dfcn5
world_rank | university_name | country | teaching | international | research | citations | income | total_score | num_students | student_staff_ratio | international_students | female_male_ratio | year | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
36 | 37 | Peking University | China | 76.4 | 68.6 | 61.3 | 72.2 | 98.6 | 70.7 | 40,148 | 8.3 | 14% | NaN | 2011 |
49 | 49 | University of Science and Technology of China | China | 57.5 | - | 48.6 | 92.7 | 30.3 | 66.0 | 14,290 | 7.9 | 2% | NaN | 2011 |
57 | 58 | Tsinghua University | China | 74.9 | 43.0 | 66.6 | 52.7 | 97.8 | 64.2 | 39,763 | 13.7 | 10% | 32 : 68 | 2011 |
119 | 120 | Nanjing University | China | 52.2 | 50.2 | 46.2 | 66.0 | 43.4 | 54.6 | 29,743 | 13.3 | 10% | 46 : 54 | 2011 |
170 | 171 | Sun Yat-sen University | China | 46.2 | 29.3 | 34.7 | 70.2 | 41.2 | 49.6 | 51,351 | 16.6 | 8% | 51 : 49 | 2011 |
我们计划统计各个学校在校生相对比例,但是,会发现“num_students”特征中的数据是字符串,不是数字。因此,需要对其进行转换。
dfcn5['num_students']=dfcn5['num_students'].apply(lambda value: float(value.replace(",", "")))
dfcn5['num_students']
# out
36 40148.0
49 14290.0
57 39763.0
119 29743.0
170 51351.0
Name: num_students, dtype: float64
之后创建 go.Pie 的 Trace 实例对象,并绘制饼图。
trace = go.Pie(values = dfcn5['num_students'],
labels = dfcn5['university_name'],
domain = {'x':[0, .5]},
name = 'Number of Students Rates',
hoverinfo = 'label + percent + name',
hole = .3,
)
layout = go.Layout(title = "Universities Number of Students Rates",
annotations = [
{'font':{'size':20},
'showarrow':False,
"text": "Number of Students",
'x':0.20,
'y':1
},
]
)
figure = go.Figure(data=[trace], layout=layout)
py.offline.iplot(figure)
输出结果:
go.Pie 也是有很多参数的,这里仅对上面用到的几个参数简要说明一下,其他的参数,可以参阅官方网站的说明。
- values:用于绘制饼图的数据。
- labels:与上述数据项对应的标示。
- domain:从单词含义上看,它的意思是“领域”;其实,是当前的饼图所占据的“领域”。通常可以为 {'x': [0,1], 'y': [0, 1]},表示当前图示分别在横、纵两个方向上相对图示默认坐标的范围分布,例如本例中以 domain = {'x':[0, .5]} 表示当前图示(即 Trace 对象)在图示坐标横轴上的范围是:从 0 开始,到最大刻度的 50% 止。
- name:当前 Trace 对象(图示)的名称。
- hoverinfo:当鼠标移动到每个扇区的时候,会显示相应的说明文字,就是这个参数确定的。
- hole:如果仔细观察上图,其实它不是真正意义的饼图,严谨地说,这张图应该名曰“环形图”,因为中间有一个洞(hole),这个洞就让“饼”变成“环”了。参数 hole 就是控制这个洞大小的,其值为浮点数,表示洞的半径相对饼半径的大小。如果将 hole 参数去掉,或者 hole=0,那么得到的才是真正意义的“饼图”,如下图所示。
本来,如果创建了 go.Pie 的 Trace 对象,然后就执行语句 py.offline.iplot([trace]),就能够得到饼图(环形图)了。但是,有时候我们还需要对输出的结果在布局上进行设置,因此常常再使用 go.Layout 创建一个专门的实例对象。并且在上面的示例中,使用了 go.Layout 类中的参数 annotations,代表了标注图示文本的有关属性。
colors = ['#FEBFB3', '#E1396C', '#96D38C', '#D0F9B1', '##CD5C5C']
trace = go.Pie(values = dfcn5['num_students'],
labels = dfcn5['university_name'],
rotation = 45,
opacity = 0.5,
showlegend = False,
pull = [0.1, 0, 0, 0, 0],
hoverinfo = 'label + percent',
textinfo = 'value',
textfont = dict(size=20, color='white'),
marker = dict(colors = colors,
line = dict(color="#333333", width=2)
)
)
py.offline.iplot([trace])
输出结果:
这次得到的饼图跟前面的稍有不同,其变化之因皆由 go.Pie 中引入的几个新参数而来。
- rotation:默认状态,饼图的开始是从 12 点钟位置,通过此函数,将饼图进行旋转。
- opacity:设置显示图的透明度。
- showlegend:控制是否显示图例。
- pull:以列表形式显示每个扇形区是否突出出来,列表中的“0.1”表示第一个扇区突出,并用数值表示分离的相对距离(相对半径长度)。
- textinfo:设置每个扇区上显示数值('value')还是百分比('percent')。
- marker:设置每个扇形的属性,比如颜色、线条的颜色和宽度等。
在同一个 Data 中,也可以集成多个 go.Pie 的 Trace 对象,并且通过对布局的设置,能够满足更多的显示需要。下面的示例是对前述所学内容的综合展示,请认真品读。
# 获取数据集中美国的 TOP 5 学校
dfusa = df[df['country']=='United States of America']
dfusa5 = dfusa.iloc[:5, :]
dfusa5['num_students'] = dfusa5['num_students'].apply(lambda value: float(value.replace(",", ""))) # 将字符串转化为浮点数
trace0 = go.Pie(values = dfcn5['num_students'],
labels = dfcn5['university_name'],
domain = dict(x=[0, .45]),
name = 'China Top5',
showlegend = False,
hoverinfo = 'label + percent + name',
textinfo = 'percent',
hole = 0.4
)
trace1 = go.Pie(values = dfusa5['num_students'],
labels = dfusa5['university_name'],
domain = dict(x=[0.55, 1]),
name = 'USA Top5',
showlegend = False,
hoverinfo = 'label + percent + name',
textinfo = 'percent',
hole = 0.4
)
data = go.Data([trace0, trace1])
layout = go.Layout(title="TOP5 of China and USA",
annotations = [dict(font={"size":20}, # 文字大小
showarrow=False,
text='China', # 显示在环形图中央的文本
x=0.18, # 文本的显示位置
y=0.5,
),
dict(font={'size':20},
showarrow=False,
text='USA',
x=0.81,
y=0.5
)]
)
figure = go.Figure(data=data, layout=layout)
py.offline.iplot(figure)
输出结果: