Matplotlib绘制饼图

0. 概述

饼图会出现在很多需要呈现各部分在整体中比重的场合,而且会有一系列的变种,这里把常见的一些饼图及绘制方式整理一下。

当然这里不可能覆盖所有的场景,不过通过对一些参数的演示和讲解,相信大家也可以绘制出符合自己需求的饼图。

1. 基本绘制方法

使用Matplotlib的pie方法可以很方便的绘制饼图,其底层的实现应该是使用到了matplotlib.patches下的Wedge对象。

一个命令就可以调用该函数,然后绘制图形,以下几行的代码就可以绘制并显示一个饼图:

fig,ax=plt.subplots()
values=rd.randint(20,60,5) #五个介于20到60之间的随机数
ax.pie(values)
plt.show()

运行效果如下:

2. 其他元素

当然,上面的例子还缺少不少元素,例如每一部分所代表的含义,以及百分比分别代表的是什么并不清晰,可以在pie中添加一些参数,例如:

import numpy as np
import matplotlib.pyplot as plt
import numpy.random as rd
from matplotlib import cm
fig,ax=plt.subplots()
values=rd.randint(20,60,5) #五个介于20到60之间的随机数
labels=['A','B','C','D','E'] #标签
colors=cm.rainbow(np.linspace(0,1,len(values))) #颜色
#指定labels和colors参数,并设置autopct参数,以百分比形式显示饼图的值
ax.pie(values,labels=labels,colors=colors,autopct='%1.1f%%')
plt.show()

运行效果如下:

另外,可以通过指定labeldistance和pctdistance调节显示标签到圆心的相对距离。

3. 阴影和分离

通过shadow和explode参数还可以指定阴影和分离效果,以突出重点,例如:

import numpy as np
import matplotlib.pyplot as plt
import numpy.random as rd
from matplotlib import cm
fig,ax=plt.subplots()
values=rd.randint(20,60,5) #五个介于20到60之间的随机数
labels=['A','B','C','D','E'] #标签
colors=cm.rainbow(np.linspace(0,1,len(values))) #颜色
#指定labels和colors参数,并设置autopct参数,以百分比形式显示饼图的值
explode=[0.1,0,0.2,0,0] #突出显示的部分
ax.pie(values,labels=labels,colors=colors,autopct='%1.1f%%',
    explode=explode,shadow=True)
plt.show()

参数Shadow决定是否带阴影,而explode列表,确定了对应份在径向上的分离程度,上面的代码中,A对应的是0.1,而C对应的是0.2,显然C比A更加远离圆心。效果如下:

4. 起始角度和方向

前面的几个图我们可以看到起始角度是从0度开始,并且采用逆时针方式进行绘制的,起始也可以通过参数startangle和counterclock(逆时针),指定起始角度和旋转方向。需要注意的是,起始角度以度为单位,因此180表示半圈,此外,无论绘制饼图是顺时针还是逆时针,起始角度总是按逆时针为正,顺时针为负。示例代码及效果如下:

import numpy as np
import matplotlib.pyplot as plt
import numpy.random as rd
from matplotlib import cm
fig,ax=plt.subplots()
values=rd.randint(20,60,5) #五个介于20到60之间的随机数
labels=['A','B','C','D','E'] #标签
colors=cm.rainbow(np.linspace(0,1,len(values))) #颜色
ax.pie(values,labels=labels,colors=colors,autopct='%1.1f%%',
    startangle=90,counterclock=False)
plt.show()

5. 环形饼图

有时候需要绘制环形饼图的样式,这个可以通过wedgeprops参数来配置:

# 环形饼图
import matplotlib.pyplot as plt

# 数据
sizes = [30, 25, 20, 15, 10]
labels = ['A', 'B', 'C', 'D', 'E']
colors = ['#ff9999','#66b3ff','#99ff99','#ffcc99','#c2c2f0']

r=1
k=0.382
# 若想让饼图为满圆,则k=1
plt.pie(sizes, 
        labels=labels, 
        radius=r, 
        colors=colors, 
        startangle=90, 
        autopct='%.2f%%', 
        pctdistance=0.8, 
        wedgeprops=dict(width=r*k,edgecolor='w'))
plt.legend(loc='upper right', bbox_to_anchor=(r,r))
# Equal aspect ratio ensures that pie is drawn as a circle.
plt.axis('equal')  
plt.title('circular pie chart')
plt.show()

效果如下:

6. 嵌套环形饼图

嵌套环形饼图起始和环形饼图完全一样,就是画两遍饼图,唯一需要注意的是两次饼图的内径和外径,示例代码如下(来自matplotlib官网):

import numpy as np
import matplotlib.pyplot as plt
import numpy.random as rd
from matplotlib import cm
fig, ax = plt.subplots()

size = 0.3
vals = np.array([[60., 32.], [37., 40.], [29., 10.]])

tab20c = plt.color_sequences["tab20c"]
outer_colors = [tab20c[i] for i in [0, 4, 8]]
inner_colors = [tab20c[i] for i in [1, 2, 5, 6, 9, 10]]

ax.pie(vals.sum(axis=1), radius=1, colors=outer_colors,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.pie(vals.flatten(), radius=1-size, colors=inner_colors,
       wedgeprops=dict(width=size, edgecolor='w'))

ax.set(aspect="equal", title='Pie plot with `ax.pie`')
plt.show()

效果如下:

7.  带标注饼图

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm

labels = ['Apple', 'Banana', 'Orange','Mango','Grapes','watermelon']
values=np.random.randint(20,100,len(labels))
colors = cm.Spectral(np.linspace(0, 1, len(labels)))

fig, ax = plt.subplots()
wedges, _ = ax.pie(values,colors=colors, startangle=90)

# add annotations
kw = dict(arrowprops=dict(arrowstyle="-|>", color='blue'),
              bbox=dict(boxstyle="round", fc="darkgray", ec=None), zorder=0, va="center")
total=sum(values)
pct=[100*x / total for x in values]
for i, p in enumerate(wedges):
    ang = (p.theta2 - p.theta1)/2. + p.theta1
    kw['arrowprops'].update({'connectionstyle': f'angle,angleA=0,angleB={ang}'})
    y = np.sin(np.deg2rad(ang))
    x = np.cos(np.deg2rad(ang))
    horizontalalignment = {-1: "right", 1: "left"}[int(np.sign(x))]
    connectionstyle = "angle,angleA=0,angleB={}".format(ang)
    
    ax.annotate(f'{pct[i]:.1f}% {labels[i]}', xy=(x, y), color='white',xytext=(1.3*np.sign(x), 1.2*y),
                horizontalalignment=horizontalalignment, **kw)

ax.set_xlim(-1.5, 1.5)
ax.set_ylim(-1.5, 1.5)
ax.set_aspect('equal')
ax.set_title('Pie Chart with Annotations')
plt.show()

效果如下:

8. 配置不同填充

前面介绍的那么多,每个扇区的样式都是纯色的,也可以通过hatch参数指定不一样的填充形式,例如:

import numpy as np
import matplotlib.pyplot as plt
import numpy.random as rd
from matplotlib import cm
fig,ax=plt.subplots()
values=rd.randint(20,60,5) #五个介于20到60之间的随机数
labels=['A','B','C','D','E'] #标签
colors=cm.rainbow(np.linspace(0,1,len(values))) #颜色
hatches = ['//', '\\\\', '||', '--', '++'] # 条纹样式
ax.pie(values,labels=labels,colors=colors,autopct='%1.1f%%',hatch=hatches)
plt.show()

效果如下:

更多填充样式可参考:填充样式https://matplotlib.org/stable/gallery/shapes_and_collections/hatch_style_reference.htmlhttps://matplotlib.org/stable/gallery/shapes_and_collections/hatch_style_reference.htmlhttps://matplotlib.org/stable/gallery/shapes_and_collections/hatch_style_reference.htmlhttps://matplotlib.org/stable/gallery/shapes_and_collections/hatch_style_reference.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值