天天看點

Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案

前言

matplotlib 提供的所有繪圖都帶有預設樣式。雖然這可以進行快速繪圖,但有時可能需要自定義繪圖的顔色和樣式,以對繪制更加精美、符合審美要求的圖像。matplotlib 的設計考慮到了此需求,可以很容易調整 matplotlib 圖形的顔色和樣式。  

自定義顔色

在生活中,我們可能對色彩的搭配與審美有自己的偏好,是以,我們可能希望 matplotlib 遵循自定義的顔色方案,以便所繪制的圖形更好地适合文檔或網頁。

matplotlib 中有多種定義顔色的方法,常見的方法包括:

1.  三元組 (Triplets):顔色可以描述為一個實數三元組,即顔色的紅、藍、綠分量,其中每個分量在 [0,1] 區間内。是以,(1.0, 0.0, 0.0) 表示純紅色,而 (1.0, 0.0, 1.0) 則表示粉色。

2. 四元組 (Quadruplets):它們前三個元素與三元組定義相同,第四個元素定義透明度值。此值也在 [0,1] 區間内。将圖形渲染到圖檔檔案中時,使用透明顔色可以使繪制圖形與背景進行混合。

3. 預定義名稱:matplotlib 将标準 HTML 顔色名稱解釋為實際顔色。例如,字元串 red 即可表示為紅色。同時一些某些顔色的具有簡潔的别名,如下表所示:

别名 顔色
b blue
g green
r red
c cyan
m magenta
y yellow
k black
w white

4. HTML 顔色字元串:matplotlib 可以将 HTML 顔色字元串解釋為實際顔色。這些字元串被定義為 #RRGGBB,其中 RR、GG 和 BB 是使用十六進制編碼的紅色、綠色和藍色分量。

5. 灰階字元串:matplotlib 将浮點值的字元串表示形式解釋為灰階,例如 0.75 表示中淺灰色。

使用自定義顔色繪制曲線圖

通過設定 plt.plot() 函數的參數 color (或等效的簡寫為 c ),可以設定曲線的顔色,如下所示:

import numpy as np
import matplotlib.pyplot as plt
def pdf(x, mu, sigma):
    a = 1. / (sigma * np.sqrt(2. * np.pi))
    b = -1. / (2. * sigma ** 2)
    return a * np.exp(b * (x - mu) ** 2)
x = np.linspace(-6, 6, 1000)
for i in range(5):
    samples = np.random.standard_normal(50)
    mu, sigma = np.mean(samples), np.std(samples)
    plt.plot(x, pdf(x, mu, sigma), color = str(.15*(i+1)))
plt.plot(x, pdf(x, 0., 1.), color = 'k')
plt.plot(x, pdf(x, 0.2, 1.), color = '#00ff00')
plt.plot(x, pdf(x, 0.4, 1.), color = (0.9,0.9,0.0))
plt.plot(x, pdf(x, 0.4, 1.), color = (0.9,0.9,0.0,0.8))
plt.show()      
Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案

使用自定義顔色繪制散點圖

可以以同樣的方式像控制曲線圖一樣控制散點圖的顔色。有兩種可用的形式:

1. 為所有點使用相同的顔色 :所有點都将以相同的顔色顯示。

2. 為每個點定義不同的顔色:為每個點提供不同的顔色。

為所有點使用相同的顔色  

利用從二進制高斯分布中提取的兩組點 y_1 和 y_2,每一組中點的顔色相同:

import numpy as np
import matplotlib.pyplot as plt
y_1 = np.random.standard_normal((150, 2))
y_1 += np.array((-1, -1)) # Center the distrib. at <-1, -1>
y_2 = np.random.standard_normal((150, 2))
y_2 += np.array((1, 1)) # Center the distrib. at <1, 1>
plt.scatter(y_1[:,0], y_1[:,1], color = 'c')
plt.scatter(y_2[:,0], y_2[:,1], color = 'b')
plt.show()      
Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案

為每個點定義不同的顔色

我們總會遇到這樣的繪圖場景,需要為不同類别的點使用不同的顔色進行繪制,以觀察不同類别間的差異情況。以

Fisher's iris資料集

為例,其資料集中資料類似如下所示:

5.0,3.3,1.4,0.2,Iris-setosa
7.0,3.2,4.7,1.4,Iris-versicolo      

資料集的每個點都存儲在以逗号分隔的清單中。最後一列給出每個點的标簽(标簽包含三類:Iris-virginica、Iris-versicolor 和 Iris-Vertosa)。在示例中,這些點的顔色将取決于它們的标簽,如下所示:

import numpy as np
import matplotlib.pyplot as plt
label_set = (
    b'Iris-setosa',
    b'Iris-versicolor',
    b'Iris-virginica',
)
def read_label(label):
    return label_set.index(label)
data = np.loadtxt('iris.data', delimiter = ',', converters = { 4 : read_label })
color_set = ('c', 'y', 'm')
color_list = [color_set[int(label)] for label in data[:,4]]
plt.scatter(data[:,0], data[:,1], color = color_list)
plt.show()      
Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案

Tips:對于三種可能的标簽,分别指定一種唯一的顔色。顔色在 color_set 中定義,标簽在 label_set 中定義。label_set 中的第 i 個标簽與 color_set 中的第i個顔色相關聯。然後我們利用它們把标簽清單轉換成顔色清單 color_list。然後隻需調用 plt.scatter() 一次即可顯示所有點及其顔色。我們也可以通過對三個不同的類别單獨調用 plt.scatter() 來實作,但這将需要更多的代碼。另外需要注意的是:如果兩點有可能有相同的坐标,但有不同的标簽,顯示的顔色将是後繪制點的顔色,可以使用透明顔色,用來顯示重疊點。

為散點圖中資料點的邊使用自定義顔色

與color參數控制點的顔色一樣,可以使用edgecolor參數控制資料點的邊的顔色。可以為每個點的邊設定相同的顔色:

import numpy as np
import matplotlib.pyplot as plt
data = np.random.standard_normal((100, 2))
plt.scatter(data[:,0], data[:,1], color = '1.0', edgecolor='r')
plt.show()      
Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案

Tips:也可以像在為每個點定義不同的顔色部分中介紹的一樣為每個點的邊設定不邊的顔色

使用自定義顔色繪制條形圖

控制繪制條形圖使用的顔色與曲線圖和散點圖的工作原理相同,即通過可選參數 color:

import numpy as np
import matplotlib.pyplot as plt
w_pop = np.array([5., 30., 45., 22.])
m_pop = np.array( [5., 25., 50., 20.])
x = np.arange(4)
plt.barh(x, w_pop, color='m')
plt.barh(x, -m_pop, color='c')
plt.show()      

![使用自定義顔色繪制條形圖](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/519a3ef28c974e9e80b02e86f92b2e8c~tplv-k3u1fbpfcp-watermark.image?)

Tips:使用 pyplot.bar() 和 pyplot.barh() 函數自定義顔色繪制條形圖的工作方式與 pyplot.scatter() 完全相同,隻需設定可選參數 color,同時也可以參數 edgecolor 控制條形邊的顔色。

import numpy as np
import matplotlib.pyplot as plt
values = np.random.random_integers(99, size = 50)
color_set = ('c', 'm', 'y', 'b')
color_list = [color_set[(len(color_set) * val) // 100] for val in values]
plt.bar(np.arange(len(values)), values, color = color_list)
plt.show()      
Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案

使用自定義顔色繪制餅圖

自定義餅圖顔色的方法類似于條形圖:

import numpy as np
import matplotlib.pyplot as plt
color_set = ('c', 'm', 'y', 'b')
values = np.random.rand(6)
plt.pie(values, colors = color_set)
plt.show()      
Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案

Tips:餅圖接受使用 colors 參數(注意,此處是 colors,而不是在 plt.plot() 中使用的color )的顔色清單。但是,如果顔色數少于輸入值清單中的元素數,那麼 plt.pie() 将循環使用顔色清單中的顔色。在示例中,使用包含四種顔色的清單,為包含六個值的餅圖着色,是以,其中有兩個顔色将使用兩次。

使用自定義顔色繪制箱型圖

将箱型圖中線條顔色進行修改:

import numpy as np
import matplotlib.pyplot as plt
values = np.random.randn(100)
b = plt.boxplot(values)
for name, line_list in b.items():
    for line in line_list:
        line.set_color('m')
plt.show()      
Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案

使用色彩映射繪制散點圖

如果要在圖形中使用多種顔色,逐個定義每種顔色并不是最佳方案,色彩映射可以解決此問題。色彩映射用一個變量對應一個值(顔色)的連續函數定義顔色。matplotlib 提供了幾種常見的顔色映射;大多數是連續的顔色漸變。

色彩映射在 matplotib.cm 子產品中定義,提供建立和使用色彩映射的函數,它還提供了預定義的色彩映射選擇。

函數 pyplot.scatter() 接受 color 參數的值清單,當提供 cmap 參數時,這些值将被解釋為色彩映射的索引:

import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt
n = 256
angle = np.linspace(0, 8 * 2 * np.pi, n)
radius = np.linspace(.5, 1., n)
x = radius * np.cos(angle)
y = radius * np.sin(angle)
plt.scatter(x, y, c = angle, cmap = cm.hsv)
plt.show()      
Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案

Tips:在 matplotlib.cm 子產品中提供了大量預定義的色彩映射,其中 cm.hsv 包含全光譜的顔色。

使用色彩映射繪制條形圖

plt.scatter() 函數内置了對色彩映射的支援,其他一些繪圖函數也内置支援色彩映射。但是,有些函數(如 pyplot.bar() )并未内置對色彩映射的支援。但是 matplotlib 可以從顔色映射顯式生成顔色:

import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import matplotlib.colors as col
values = np.random.random_integers(99, size = 50)
cmap = cm.ScalarMappable(col.Normalize(0, 99), cm.binary)
plt.bar(np.arange(len(values)), values, color = cmap.to_rgba(values))
plt.show()      
Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案

Tips:首先建立色彩映射 cmap,以便将 [0, 99] 範圍内的值映射到 matplotlib.cm.binary 的顔色。然後,函數 cmap.to_rgba 将值清單轉換為顔色清單。是以,盡管 plt.bar 并未内置色彩映射支援,但依舊可以使用并不複雜的代碼實作色彩映射。

建立自定義配色方案

matplotlib 使用的預設顔色考慮的主要對象是列印文檔或出版物。是以,預設情況下,背景為白色,而标簽、軸和其他注釋則顯示為黑色,在某些不同的使用環境中,我們可能需要使用的配色方案;例如,将圖形背景設定為黑色,注釋設定為白色。

在 matplotlib 中,各種對象(如軸、圖形和标簽)都可以單獨修改。但逐個更改這些對象的顔色配置并非最佳方案。在 matplotlib 中,所有對象都可以利用集中式配置修改其預設顔色:  

import numpy as np
import matplotlib as mpl
from matplotlib import pyplot as plt
mpl.rc('lines', linewidth = 2.)
mpl.rc('axes', facecolor = 'k', edgecolor = 'w')
mpl.rc('xtick', color = 'w')
mpl.rc('ytick', color = 'w')
mpl.rc('text', color = 'w')
mpl.rc('figure', facecolor = 'k', edgecolor ='w')
mpl.rc('axes', prop_cycle = mpl.cycler(color=[(0.1, .5, .75),(0.5, .5, .75)]))
x = np.linspace(0, 7, 1024)
plt.plot(x, np.sin(x))
plt.plot(x, np.cos(x))
plt.show()      
Matplotlib使用自定義顔色繪制統計圖前言自定義顔色建立自定義配色方案