1. 程式人生 > >從零開始學matplotlib畫圖(三): 堆積圖

從零開始學matplotlib畫圖(三): 堆積圖

堆積圖常用於綜合展示不同分類的指標趨勢以及它們的總和的趨勢。比如說,我們想看一下過去二十年來中國人口總量的變化趨勢,同時,我們又想看一下男、女性人口各自的變化趨勢,甚至我們還想看一下它們各自佔比的變化趨勢,這時,我們就可以用堆積圖來更高效、更簡潔地展示出來。


###############################################################################
#_____________________________________________________________________________#
#| ______ ___ __________ ___ __ |# #| / __ \ / | /___ ___/ / | / / |# #| / / \ | / /| | /* / /| | / / DataInsights |# #| / / / / / /_| | `/ / / | | / / |# #| / / / / / ___ | / ` / / | | / /
[email protected]
|#
#| / /___/ / / / | | ___ `/__ / / | |/ / |# #|/_________/ /_/ |_|/________//_/ |___/ https://data-insights.cn/ |# #|___________________________________________________________________________|# ###############################################################################

我們舉這樣一個例子,有一個班裡有20名學生,它們的編號分別是0-19,y1、y2、y3分別代表本次月考他們的語文、數學和英語的成績,我們想觀察這些學生的總成績以及各科成績的情況。

1. 堆積柱狀圖

首先,我們使用堆積柱狀圖來達到我們的目的:

import matplotlib.pyplot as plt
import numpy as np

# 生成資料
x = np.linspace(0, 20, 20)
y1 = np.random.randint(50, 100, 20)
y2 = np.random.randint(50, 100, 20)
y3 = np.random.randint(50, 100, 20)

# 堆積柱狀圖
plt.bar(x, y1, color='r', label='語文')
plt.bar(x, y2, bottom=y1, color='g', label='數學')
plt.bar(x, y3, bottom=y1+y2, color='c', label='英語')

# 顯示範圍
plt.xlim(-2, 22)
plt.ylim(0, 280)

# 新增圖例
plt.legend(loc='upper right')


plt.show()

可以看到,有四位同學的總成績高於250分,還有些同學嚴重偏科,另外有一個同學平均下來在及格線下方……大家不同太為他擔心,因為這些都是隨機生成的資料。

我們還可以將柱子橫過來:

import matplotlib.pyplot as plt
import numpy as np

# 生成資料
x = np.linspace(0, 20, 20)
y1 = np.random.randint(50, 100, 20)
y2 = np.random.randint(50, 100, 20)
y3 = np.random.randint(50, 100, 20)

# 堆積柱狀圖
plt.barh(x, y1, color='r', label='語文')
plt.barh(x, y2, left=y1, color='g', label='數學')
plt.barh(x, y3, left=y1+y2, color='c', label='英語')

# 顯示範圍
plt.ylim(-2, 22)
plt.xlim(0, 300)

# 新增圖例
plt.legend(loc='lower right')

plt.show()

我們需要將bottom引數的名字改成left,這樣更符合我們的視覺認知,其他引數上沒有什麼分別。

2. 堆積折線圖

這次,我們假設小明參加了20次月考,我們想看下他的總成績以及語數外三科成績的變化趨勢。

import matplotlib.pyplot as plt
import numpy as np

# 生成資料
# 假設一個班裡有20名學生,x代表他們的編號,y1/y2/y3分別是他們本次月考的成績。
x = np.linspace(0, 20, 20)
y1 = np.random.randint(50, 100, 20)
y2 = np.random.randint(50, 100, 20)
y3 = np.random.randint(50, 100, 20)

# 堆積柱狀圖
plt.stackplot(x, y1, y2, y3, baseline='zero', labels=['語文', '數學', '英語'], colors=['r', 'g', 'c'])

# 顯示範圍
plt.xlim(-2, 22)
plt.ylim(0, 300)

# 新增圖例和網格線
plt.legend(loc='upper right')
plt.grid(axis='y', color='gray', linestyle=':', linewidth=2)

plt.show()

嗯……小明的成績太不穩定了,不過還好,平均成績還沒到過及格線以下。從這張圖裡邊,我們看不到明顯的上升或者下降的趨勢。

這樣我們看到了成績的變化趨勢,但是我們不能清楚地分辨小明哪科成績更好,哪科成績是短板,因此我們需要看一下小明的總成績中各科成績佔比的變化趨勢。

import matplotlib.pyplot as plt
import numpy as np

# 生成資料
# 假設一個班裡有20名學生,x代表他們的編號,y1/y2/y3分別是他們本次月考的成績。
x = np.linspace(0, 20, 20)
y1 = np.random.randint(50, 100, 20)
y2 = np.random.randint(50, 100, 20)
y3 = np.random.randint(50, 100, 20)

# 計算百分比
y1p = y1 / (y1 + y2 + y3)
y2p = y2 / (y1 + y2 + y3)
y3p = y3 / (y1 + y2 + y3)

# 比例堆積柱狀圖
plt.stackplot(x, y1p, y2p, y3p, baseline='zero', labels=['語文', '數學', '英語'], colors=['r', 'g', 'c'])

# 顯示範圍
plt.xlim(0, 20)
plt.ylim(0, 1)

# 新增圖例
plt.legend(loc='upper right')
plt.grid(axis='y', color='gray', linestyle=':', linewidth=2)

plt.show()

由於這裡各科的成績都是我們隨機生成的,所以我們從圖中並不能看出來小明的強弱勢科目,但這種表現方式非常實用。比如我們要分析使用者結構的變化趨勢、分析內容型別分佈的趨勢等。這種圖形相當於在餅圖的基礎上增加了時間序列的維度,將多個餅圖拉伸開來,連線到一起。

今天我們展示瞭如何繪製堆積柱狀圖和堆積折線圖(面積圖),之後這一系列文章每一期會專門針對一個點來進行分享,確保每次大家能用十來分鐘就學會一項新的實用技能,這樣才不負咱們“功利主義”的“美名”。