Python繪圖工具包:matplotlib

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()
axvline繪制直線

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()
渲染對(duì)象的控制
  • 坐標(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()
坐標(biāo)軸格式化

圖例 : 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í)例1
  • 圖例:實(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í)例2
  • 圖例:實(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()

圖例:實(shí)例3
  • 點(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格式
Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末铛只,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子糠溜,更是在濱河造成了極大的恐慌淳玩,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件非竿,死亡現(xiàn)場(chǎng)離奇詭異蜕着,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)红柱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門承匣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人豹芯,你說(shuō)我怎么就攤上這事悄雅。” “怎么了铁蹈?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵宽闲,是天一觀的道長(zhǎng)众眨。 經(jīng)常有香客問(wèn)我,道長(zhǎng)容诬,這世上最難降的妖魔是什么娩梨? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮览徒,結(jié)果婚禮上狈定,老公的妹妹穿的比我還像新娘。我一直安慰自己习蓬,他們只是感情好纽什,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著躲叼,像睡著了一般芦缰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上枫慷,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天让蕾,我揣著相機(jī)與錄音,去河邊找鬼或听。 笑死探孝,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的誉裆。 我是一名探鬼主播顿颅,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼找御!你這毒婦竟也來(lái)了元镀?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤霎桅,失蹤者是張志新(化名)和其女友劉穎栖疑,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體滔驶,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡遇革,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了揭糕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片萝快。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖著角,靈堂內(nèi)的尸體忽然破棺而出揪漩,到底是詐尸還是另有隱情,我是刑警寧澤吏口,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布奄容,位于F島的核電站冰更,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏昂勒。R本人自食惡果不足惜蜀细,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望戈盈。 院中可真熱鬧奠衔,春花似錦、人聲如沸塘娶。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)血柳。三九已至官册,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間难捌,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工鸦难, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留根吁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓合蔽,卻偏偏與公主長(zhǎng)得像击敌,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拴事,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容