1. 目的
了解matplotlib
- 注意:
- python自帶交互環(huán)境德召, plt.show()猾浦, 點(diǎn)擊關(guān)閉后泉沾,可以繼續(xù)編寫(xiě)代碼
- ipython交互環(huán)境,plt.show()鞍盗, 點(diǎn)擊關(guān)閉后需了,plt.show沒(méi)有退出,無(wú)法執(zhí)行
- ipython notebook般甲, 如果要在瀏覽器中顯示繪圖結(jié)果肋乍,需要在首行添加: %matplotlib inline ,然后在編寫(xiě)代碼
2. 過(guò)程
2.1 函數(shù)
2.1.1 plot
- plot(*args, **kwargs) :主要參數(shù)見(jiàn)源碼敷存;
- *args : 即: 輸入單變量墓造,如,x軸數(shù)據(jù)和y軸數(shù)據(jù)历帚, 圖標(biāo)屬性信息
- *kwargs : 即: 參數(shù)為kv格式滔岳, 如, label=**挽牢, linewidth=
- 例子:
- plt.plot("a", "b", 'go-', data={"a": [1, 2, 3], "b": [4, 5, 6]}, label='line 1')
- plt.plot([1, 2, 3], [1, 2, 3], 'go-', label='line 1', linewidth=2)
2.1.2 plt.axvline
- 繪制垂直x軸的直線
- 實(shí)例
>>> import numpy as np;import matplotlib.pyplot as plt
>>> d1 = np.arange(0, 10, 1)
>>> d1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> for k,v in zip(d1[:-1], d1[1:]):
... plt.axvline(.5 * (k+v), color='b')
...
<matplotlib.lines.Line2D object at 0x7f18735bff90>
<matplotlib.lines.Line2D object at 0x7f18735cc610>
<matplotlib.lines.Line2D object at 0x7f18735ccb50>
<matplotlib.lines.Line2D object at 0x7f18735ccf50>
<matplotlib.lines.Line2D object at 0x7f18735d6550>
<matplotlib.lines.Line2D object at 0x7f18735d6a10>
<matplotlib.lines.Line2D object at 0x7f18735d6ed0>
<matplotlib.lines.Line2D object at 0x7f18735e43d0>
<matplotlib.lines.Line2D object at 0x7f18735e4890>
>>> plt.show()
2.2 實(shí)例
折線圖
直線: 先上例子
import matplotlib.pyplot as plt
plt.plot([0,1,2,3,4]) # 方式1:list參數(shù)谱煤,默認(rèn)為y值,自動(dòng)生成x軸值
# plt.plot([0,1,2,3,4], [1,4,32,16]) # 方式2:list參數(shù)禽拔,傳入x和y值,
plt.ylabel('some numbers')
plt.xlabel('any numbers')
plt.show()
直線: 配置畫(huà)布
- 選擇顯示模式
import matplotlib.pyplot as plt
plt.plot([1,2,3,4], [1,4,9,16], 'ro')
plt.axis([0, 6, 0, 20])
plt.show()
- 顯示多個(gè)線
import numpy as np
import matplotlib.pyplot as plt
# evenly sampled time at 200ms intervals
t = np.arange(0., 5., 0.2)
# red dashes, blue squares and green triangles
# 注意: plot 輸入的參數(shù)刘离,即使是
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()
- 設(shè)置屬性: 用key-value格式
import matplotlib.pyplot as plt
x = range(10)
y = range(5,55,5)
plt.plot(x,y, '-', linewidth=2.0)
plt.show()
- 設(shè)置屬性: 用setp()函數(shù)
import matplotlib.pyplot as plt
x1 = range(10)
y1 = range(5,55,5)
x2 = range(3,33,3)
y2 = range(2,22,2)
lines = plt.plot(x1, y1, x2, y2)
# use keyword args
plt.setp(lines, color='r', linewidth=2.0)
# or MATLAB style string value pairs
plt.setp(lines, 'color', 'r', 'linewidth', 2.0)
plt.show()
正弦曲線: 多畫(huà)布
import numpy as np
import matplotlib.pyplot as plt
def f(t):
return np.exp(-t) * np.cos(2*np.pi*t)
t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.05)
plt.figure(1)
# 默認(rèn): 如果畫(huà)布數(shù)plot小于10,且畫(huà)布的行row和列column也小于10睹栖,可以用數(shù)值代替
# 例如: plt.subplot(312) 表示plot_number=3, row=1, column=2
plt.subplot(311)
# plt.plot(t1, f(t1), 'o' ,t2, f(t2), 'o')
plt.plot(t2, f(t2), 'o')
plt.subplot(312)
# plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.plot(t1, f(t1), 'o' )
plt.subplot(313)
# plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.plot(t1, f(t1), 'o' )
plt.show()
標(biāo)簽顯示
#生成長(zhǎng)度為10硫惕,在[0,1)之間平均分布的隨機(jī)數(shù)組:
numpy.random.random(size=10)
#生成在-0.1到0.1之間的平均分布:
# 方法1:
0.2*numpy.random.random(size=10)-0.1
# 方法2:
numpy.random.uniform(-0.1,0.1,size=10)
#生成長(zhǎng)度為10,符合正態(tài)分布的隨機(jī)數(shù)
mu,sigma=0,0.1 #均值與標(biāo)準(zhǔn)差
rarray=numpy.random.normal(mu,sigma,10)
- 標(biāo)簽的添加
import numpy as np
import matplotlib.pyplot as plt
# 隨機(jī)種子野来,目的: 隨機(jī)可重現(xiàn)
np.random.seed(19680801)
# 產(chǎn)生均值100恼除, 均方差15的隨機(jī)數(shù)
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
# 直方圖
n, bins, patches = plt.hist(x, 50, normed=1, facecolor='g', alpha=0.75)
# 添加軸標(biāo)簽
# 注意:不能顯示中文
plt.xlabel("I am x axes")
# plt.xlabel('I am x axes', fontsize=14, color='red') # 試試修改標(biāo)簽的屬性
plt.ylabel("I am y axes")
plt.title('XX histogram, The name must English, Not Chinese')
# 添加文字標(biāo)簽
plt.text(60, 0.025, r'$\mu=100, \sigma=15, $')
plt.axis([40,160, 0, 0.03])
# 顯示柵格
plt.grid(True)
plt.show()
- 添加注解:Annotating
import numpy as np
import matplotlib.pylab as plt
ax = plt.subplot(111)
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)
# xy:
plt.annotate('local max', xy=(2,1) , xytext=(1, 1.5), arrowprops=dict(facecolor='black', shrink=0.1), )
plt.ylim(-2,2)
plt.show()
非線性圖
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter # useful for `logit` scale
# Fixing random state for reproducibility
np.random.seed(19680801)
# make up some data in the interval ]0, 1[
y = np.random.normal(loc=0.5, scale=0.4, size=1000)
y = y[(y > 0) & (y < 1)]
y.sort()
x = np.arange(len(y))
# plot with various axes scales
plt.figure(1)
# linear
plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)
# log
plt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)
# symmetric log
plt.subplot(223)
plt.plot(x, y - y.mean())
plt.yscale('symlog', linthreshy=0.01)
plt.title('symlog')
plt.grid(True)
# logit
# 注意版本,1.3沒(méi)有l(wèi)ogit曼氛,后來(lái)安裝2.1.0rc1后可以正常顯示logit的圖
plt.subplot(224)
plt.plot(x, y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)
# Format the minor tick labels of the y-axis into empty strings with
# `NullFormatter`, to avoid cumbering the axis with too many labels.
plt.gca().yaxis.set_minor_formatter(NullFormatter())
# Adjust the subplot layout, because the logit one may take more space
# than usual, due to y-tick labels like "1 - 10^{-3}"
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
wspace=0.35)
plt.show()
子圖的布局
- 拼圖模式
import matplotlib.pyplot as plt
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3) # 生成3x3的格子豁辉,第一行,1個(gè)子圖舀患,寬度占滿3格
ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2) # 第二行徽级,第一個(gè)子圖,寬度占2格
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2) # 第二行聊浅,第二個(gè)子圖餐抢,寬度默認(rèn)占1格现使,高度占2格
ax4 = plt.subplot2grid((3, 3), (2, 0))
ax5 = plt.subplot2grid((3, 3), (2, 1))
plt.show()
# 等效下面代碼
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(3, 3)
ax1 = plt.subplot(gs[0, :])
ax2 = plt.subplot(gs[1, :-1])
ax3 = plt.subplot(gs[1:, -1])
ax4 = plt.subplot(gs[-1, 0])
ax5 = plt.subplot(gs[-1, -2])
# 也可以直接定義,長(zhǎng)款
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(2, 2,
width_ratios=[1, 2],
height_ratios=[4, 1]
) # 相當(dāng)于把豆腐寬度切了左邊三分之一旷痕,然后下部五分之一再切一刀
ax1 = plt.subplot(gs[0])
ax2 = plt.subplot(gs[1])
ax3 = plt.subplot(gs[2])
ax4 = plt.subplot(gs[3])
- 多格顯示單圖
'''
import matplotlib.pyplot as plt
ax = plt.subplot2grid((2, 2), (0, 0)) # 創(chuàng)建2x2格子碳锈,單只顯示左上角格子
plt.show()
等效于下面代碼
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(2, 2)
ax = plt.subplot(gs[0, 0])
plt.show()
'''
多個(gè)子圖的標(biāo)簽: 不重疊
import matplotlib.pyplot as plt
plt.rcParams['savefig.facecolor'] = "0.8"
def example_plot(ax, fontsize=12):
ax.plot([1, 2])
ax.locator_params(nbins=10)
ax.set_xlabel('x-label', fontsize=fontsize)
ax.set_ylabel('y-label', fontsize=fontsize)
ax.set_title('Title', fontsize=fontsize)
plt.close('all')
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2)
example_plot(ax1)
example_plot(ax2)
example_plot(ax3)
example_plot(ax4)
#如下代碼,加上后苦蒿,就不會(huì)產(chǎn)生便簽重疊
plt.tight_layout()
# plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)
plt.show()
- 多圖空間布局
plt.close('all')
fig = plt.figure()
import matplotlib.gridspec as gridspec
def example_plot(ax, fontsize=12):
ax.plot([1, 2])
ax.locator_params(nbins=10)
ax.set_xlabel('x-label', fontsize=fontsize)
ax.set_ylabel('y-label', fontsize=fontsize)
ax.set_title('Title', fontsize=fontsize)
gs1 = gridspec.GridSpec(2, 1)
ax1 = fig.add_subplot(gs1[0])
ax2 = fig.add_subplot(gs1[1])
# ax3 = fig.add_subplot(gs1[2])
example_plot(ax1)
example_plot(ax2)
# example_plot(ax3)
# gs1在畫(huà)布的位置殴胧,由rect定義, 兩個(gè)點(diǎn)確定一個(gè)矩形, 即定義畫(huà)布的左半邊佩迟,歸gs1顯示
# 點(diǎn)1 (0,0) : 左上角位置
# 點(diǎn)2 (0.5,1) : 底部中間位置
gs1.tight_layout(fig, rect=[0, 0, 0.5, 1])
gs2 = gridspec.GridSpec(3, 1)
for ss in gs2:
ax = fig.add_subplot(ss)
example_plot(ax)
ax.set_title("")
ax.set_xlabel("")
ax.set_xlabel("x-label", fontsize=12)
# gs2在畫(huà)布的位置,由rect定義, 兩個(gè)點(diǎn)確定一個(gè)矩形竿屹, 即定義畫(huà)布的左半邊报强,歸gs2顯示
gs2.tight_layout(fig, rect=[0.5, 0, 1, 1], h_pad=0.5)
plt.show()
matplotlib中級(jí)進(jìn)階:藝術(shù)家教程
matplotlib結(jié)構(gòu)
matplotlib.backend_bases.FigureCanvas : 畫(huà)布, 圖片繪制區(qū)域
matplotlib.backend_bases.Renderer : 渲染對(duì)象拱燃,繪制到畫(huà)布的元素
matplotlib.artist.Artist : 用渲染對(duì)象秉溉,畫(huà)在畫(huà)布上,包括布局碗誉,標(biāo)簽召嘶,線等
Subplot is just a subclass of Axes : subplot 是 Axes的子類
渲染對(duì)象的控制
import numpy as np
import matplotlib.pyplot as plt
# plt.figure creates a matplotlib.figure.Figure instance
fig = plt.figure()
rect = fig.patch # a rectangle instance
rect.set_facecolor('lightgoldenrodyellow')
ax1 = fig.add_axes([0.1, 0.3, 0.4, 0.4])
rect = ax1.patch
rect.set_facecolor('lightslategray')
for label in ax1.xaxis.get_ticklabels():
# label is a Text instance
label.set_color('red')
label.set_rotation(45) # 標(biāo)簽旋轉(zhuǎn)角度
label.set_fontsize(16) # 標(biāo)簽字體大小
for line in ax1.yaxis.get_ticklines():
# line is a Line2D instance
line.set_color('green')
line.set_markersize(25) # 單位分割線的長(zhǎng)度
line.set_markeredgewidth(3)
plt.show()
- 坐標(biāo)軸格式化
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
# Fixing random state for reproducibility
np.random.seed(19680801)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(100*np.random.rand(20))
formatter = ticker.FormatStrFormatter('$%1.2f')
ax.yaxis.set_major_formatter(formatter)
for tick in ax.yaxis.get_major_ticks():
tick.label1On = True # 左邊坐標(biāo)軸
tick.label2On = True # 右邊坐標(biāo)軸
tick.label2.set_color('green')
plt.show()
圖例 : legend
- 空白畫(huà)布添加圖例
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
red_patch = mpatches.Patch(color='red', label='The red data')
plt.legend(handles=[red_patch])
plt.show()
- 圖例:實(shí)例1
import matplotlib.pyplot as plt
plt.subplot(211)
plt.plot([1,2,3], label="test1")
plt.plot([3,2,1], label="test2")
# Place a legend above this subplot, expanding itself to
# fully use the given bounding box.
plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
ncol=2, mode="expand", borderaxespad=0.)
plt.subplot(223)
plt.plot([1,2,3], label="test1")
plt.plot([3,2,1], label="test2")
# Place a legend to the right of this smaller subplot.
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.) # loc代表圖例的位置
plt.show()
- 圖例:實(shí)例2
import numpy as np
import matplotlib.pyplot as plt
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels)
line_up, = plt.plot([1,2,3], label='Line 2')
line_down, = plt.plot([3,2,1], label='Line 1')
plt.legend([line_up, line_down], ['Line Up', 'Line Down']) # legend 接受kv格式
plt.show()
- 圖例:實(shí)例3
import matplotlib.pyplot as plt
line1, = plt.plot([1,2,3], label="Line 1", linestyle='--')
line2, = plt.plot([3,2,1], label="Line 2", linewidth=4)
# Create a legend for the first line.
# first_legend = plt.legend(handles=[line1], loc=1) # 這種方式在 matplotlib 1.3.1 會(huì)報(bào)錯(cuò), 升級(jí)到2.0.2就沒(méi)問(wèn)題了
first_legend = plt.legend([line1],["AAA"], loc=1)
# Add the legend manually to the current Axes.
ax = plt.gca().add_artist(first_legend)
# Create another legend for the second line.
plt.legend([line2],["BBB"], loc=4)
plt.show()
- 點(diǎn)折線:實(shí)例4
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerLine2D
line1, = plt.plot([3,2,1], marker='o', label='Line 1')
line2, = plt.plot([1,2,3], marker='o', label='Line 2')
plt.legend(handler_map={line1: HandlerLine2D(numpoints=4)}) # 點(diǎn)數(shù)目哮缺,如果大于樣本數(shù)弄跌,會(huì)出現(xiàn)兩個(gè)線圖標(biāo), 可以嘗試修改numpoints值
plt.show()
- 圖標(biāo)疊加:實(shí)例5
import matplotlib.pyplot as plt
from numpy.random import randn
z = randn(10)
red_dot, = plt.plot(z, "ro", markersize=15)
# Put a white cross over some of the data.
white_cross, = plt.plot(z[:5], "w+", markeredgewidth=3, markersize=15)
plt.legend([red_dot, (red_dot, white_cross)], ["Attr A", "Attr A+B"]) # 圖標(biāo)疊加尝苇,kv格式