關(guān)于matplotlib,你要的餅圖在這里

前言

matplotlib, 官方提供的餅圖Demo,功能比較比較簡(jiǎn)單,在實(shí)際應(yīng)用過(guò)程中,往往會(huì)有許多個(gè)性化的繪制需求,在這里跟大家一起了解下餅圖(pie chart)的一些特色的功能的實(shí)現(xiàn)。

from matplotlib import font_manager as fm
import matplotlib as mpl
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
% matplotlib inline
plt.style.use('ggplot')

1. 官方Demo

import matplotlib.pyplot as plt

# Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
explode = (0, 0.1, 0, 0)  # only "explode" the 2nd slice (i.e. 'Hogs')

fig1, ax1 = plt.subplots()
ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
        shadow=True, startangle=90)
ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

plt.savefig('Demo_official.jpg')
plt.show()
Demo_official.jpg

2. 將實(shí)際數(shù)據(jù)應(yīng)用于官方Demo

# 原始數(shù)據(jù)
shapes = ['Cross', 'Cone', 'Egg', 'Teardrop', 'Chevron', 'Diamond', 'Cylinder',
       'Rectangle', 'Flash', 'Cigar', 'Changing', 'Formation', 'Oval', 'Disk',
       'Sphere', 'Fireball', 'Triangle', 'Circle', 'Light']
values = [  287,   383,   842,   866,  1187,  1405,  1495,  1620,  1717,
        2313,  2378,  3070,  4332,  5841,  6482,  7785,  9358,  9818, 20254]

s = pd.Series(values, index=shapes)
s
from matplotlib import font_manager as fm
import matplotlib as mpl

# Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = s.index
sizes = s.values
explode = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

fig1, ax1 = plt.subplots()
patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.0f%%',
        shadow=False, startangle=170)
ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

plt.savefig('Demo_project.jpg')
plt.show()
Demo_project.jpg

上圖的一些問(wèn)題:

  1. 顏色比較生硬
  2. 部分文字擁擠在一起,繪圖顯示不齊整

3. 一些改善措施

  • 重新設(shè)置字體大小
  • 設(shè)置自選顏色
  • 設(shè)置圖例
  • 將某些類(lèi)別突出顯示

3.1 重新設(shè)置字體大小

from matplotlib import font_manager as fm
import matplotlib as mpl

labels = s.index
sizes = s.values
explode = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

fig1, ax1 = plt.subplots()

patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.0f%%',
        shadow=False, startangle=170)
ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

# 重新設(shè)置字體大小
proptease = fm.FontProperties()
proptease.set_size('xx-small')
# font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'
plt.setp(autotexts, fontproperties=proptease)
plt.setp(texts, fontproperties=proptease)

plt.savefig('Demo_project_set_font.jpg')
plt.show()
Demo_project_set_font.jpg

3.2 設(shè)置顯示顏色,Method 1:

from matplotlib import font_manager as fm
import matplotlib as mpl

# Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = s.index
sizes = s.values
explode = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

fig1, ax1 = plt.subplots(figsize=(6,6)) # 設(shè)置繪圖區(qū)域大小

a = np.random.rand(1,19)
color_vals = list(a[0])
my_norm = mpl.colors.Normalize(-1, 1) # 將顏色數(shù)據(jù)的范圍設(shè)置為 [0, 1]
my_cmap = mpl.cm.get_cmap('rainbow', len(color_vals)) # 可選擇合適的colormap,如:'rainbow'

patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.0f%%',
        shadow=False, startangle=170, colors=my_cmap(my_norm(color_vals)))

ax1.axis('equal')  

# 重新設(shè)置字體大小
proptease = fm.FontProperties()
proptease.set_size('xx-small')
# font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'
plt.setp(autotexts, fontproperties=proptease)
plt.setp(texts, fontproperties=proptease)

plt.savefig('Demo_project_set_color_1.jpg')
plt.show()
Demo_project_set_color_1.jpg

上面這種方法設(shè)置顏色時(shí),但類(lèi)別比較多時(shí),部分顏色的填充會(huì)重復(fù)。

有時(shí)候,我們可能想設(shè)置成連續(xù)的顏色,可以有另外一種方法來(lái)實(shí)現(xiàn)。

3.3 設(shè)置顯示顏色, Method 2:

from matplotlib import font_manager as fm
from  matplotlib import cm

labels = s.index
sizes = s.values
# explode = (0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

fig, ax = plt.subplots(figsize=(6,6)) # 設(shè)置繪圖區(qū)域大小


colors = cm.rainbow(np.arange(len(sizes))/len(sizes)) # colormaps: Paired, autumn, rainbow, gray,spring,Darks
patches, texts, autotexts = ax.pie(sizes, labels=labels, autopct='%1.0f%%',
        shadow=False, startangle=170, colors=colors)

ax.axis('equal')  
ax.set_title('Shapes -------------------', loc='left')

# 重新設(shè)置字體大小
proptease = fm.FontProperties()
proptease.set_size('xx-small')
# font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'
plt.setp(autotexts, fontproperties=proptease)
plt.setp(texts, fontproperties=proptease)

plt.savefig('Demo_project_set_color_2.jpg')
plt.show()
Demo_project_set_color_2.jpg

從上圖可以看出,顏色顯示是連續(xù)的,實(shí)現(xiàn)了我們想要的效果

3.4 設(shè)置圖例(legend)

from matplotlib import font_manager as fm
from  matplotlib import cm

labels = s.index
sizes = s.values
# explode = (0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

fig, ax = plt.subplots(figsize=(6,6)) # 設(shè)置繪圖區(qū)域大小


colors = cm.rainbow(np.arange(len(sizes))/len(sizes)) # colormaps: Paired, autumn, rainbow, gray,spring,Darks
patches, texts, autotexts = ax.pie(sizes, labels=labels, autopct='%1.0f%%',
        shadow=False, startangle=170, colors=colors)

ax.axis('equal')  

# 重新設(shè)置字體大小
proptease = fm.FontProperties()
proptease.set_size('xx-small')
# font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'
plt.setp(autotexts, fontproperties=proptease)
plt.setp(texts, fontproperties=proptease)


ax.legend(labels, loc=2)

plt.savefig('Demo_project_set_legend_error.jpg')
plt.show()
Demo_project_set_legend_error.jpg

從上面可看出,當(dāng)類(lèi)別較多時(shí),圖例(legend)的位置擺放顯示有重疊,顯示有些問(wèn)題,需要進(jìn)行調(diào)整。

3.5 重新設(shè)置圖例(legend)

from matplotlib import font_manager as fm
from  matplotlib import cm

labels = s.index
sizes = s.values
# explode = (0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)  # only "explode" the 1st slice

fig, axes = plt.subplots(figsize=(10,5),ncols=2) # 設(shè)置繪圖區(qū)域大小
ax1, ax2 = axes.ravel()

colors = cm.rainbow(np.arange(len(sizes))/len(sizes)) # colormaps: Paired, autumn, rainbow, gray,spring,Darks
patches, texts, autotexts = ax1.pie(sizes, labels=labels, autopct='%1.0f%%',
        shadow=False, startangle=170, colors=colors)

ax1.axis('equal')  

# 重新設(shè)置字體大小
proptease = fm.FontProperties()
proptease.set_size('xx-small')
# font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'
plt.setp(autotexts, fontproperties=proptease)
plt.setp(texts, fontproperties=proptease)

ax1.set_title('Shapes', loc='center')

# ax2 只顯示圖例(legend)
ax2.axis('off')
ax2.legend(patches, labels, loc='center left')

plt.tight_layout()
plt.savefig('Demo_project_set_legend_good.jpg')
plt.show()
Demo_project_set_legend_good.jpg

3.6 將某些類(lèi)別突出顯示

  • 將某些類(lèi)別突出顯示
  • 控制label的顯示位置
  • 控制百分比的顯示位置
  • 控制突出位置的大小
from matplotlib import font_manager as fm
from  matplotlib import cm

labels = s.index
sizes = s.values
explode = (0.1,0,0,0,0,0,0,0,0,0,0,0,0,0.2,0,0,0,0.1,0)  # "explode" , show the selected slice

fig, axes = plt.subplots(figsize=(8,5),ncols=2) # 設(shè)置繪圖區(qū)域大小
ax1, ax2 = axes.ravel()

colors = cm.rainbow(np.arange(len(sizes))/len(sizes)) # colormaps: Paired, autumn, rainbow, gray,spring,Darks
patches, texts, autotexts = ax1.pie(sizes, labels=labels, autopct='%1.0f%%',explode=explode,
        shadow=False, startangle=170, colors=colors, labeldistance=1.2,pctdistance=1.03, radius=0.4)
# labeldistance: 控制labels顯示的位置
# pctdistance: 控制百分比顯示的位置
# radius: 控制切片突出的距離

ax1.axis('equal')  

# 重新設(shè)置字體大小
proptease = fm.FontProperties()
proptease.set_size('xx-small')
# font size include: ‘xx-small’,x-small’,'small’,'medium’,‘large’,‘x-large’,‘xx-large’ or number, e.g. '12'
plt.setp(autotexts, fontproperties=proptease)
plt.setp(texts, fontproperties=proptease)

ax1.set_title('Shapes', loc='center')

# ax2 只顯示圖例(legend)
ax2.axis('off')
ax2.legend(patches, labels, loc='center left')

plt.tight_layout()
# plt.savefig("pie_shape_ufo.png", bbox_inches='tight')
plt.savefig('Demo_project_final.jpg')
plt.show()
Demo_project_final.jpg

更多精彩內(nèi)容請(qǐng)關(guān)注公眾號(hào):

“Python數(shù)據(jù)之道”

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,347評(píng)論 25 708
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,688評(píng)論 4 61
  • 2017.5.16 by YolandaXu 今天早上狀態(tài)很不好,不知為什么有些煩躁。早晨開(kāi)車(chē)出來(lái)的的時(shí)候碰到前面...
    YolandaXu閱讀 486評(píng)論 3 3
  • 不經(jīng)意間打了個(gè)盹兒 太陽(yáng)便繞過(guò)整座房子 給小桌偷偷涂上昏暗的顏色 我穿過(guò)時(shí)空縫隙,瞇著眼 在夕照的影子下站定 世間...
    一川旱樹(shù)閱讀 247評(píng)論 0 6
  • 不知道看到文章標(biāo)題,親們有沒(méi)有同感,反正我是真的覺(jué)得,上個(gè)世紀(jì)五六十年代出生的人性格都比較倔。這不,我就碰到了兩...
    德馨陶吧閱讀 281評(píng)論 0 1

友情鏈接更多精彩內(nèi)容