1. 安裝和文檔
pip install matplotlib
為了方便顯示圖像,還使用了ipython qtconsole方便顯示。具體怎么弄網上搜一下就很多教程了。
pyplot模塊是提供操作matplotlib庫的經典Python接口。
# 導入pyplot
import matplotlib.pyplot as plt
2. 初探pyplot
plot()的參數表
matplotlib.pyplot.plot(*args, **kwargs)
The following format string characters are accepted to control the line style or marker:
| character | description |
|---|---|
| '-' | solid line style |
| '--' | dashed line style |
| '-.' | dash-dot line style |
| ':' | dotted line style |
| '.' | point marker |
| ',' | pixel marker |
| 'o' | circle marker |
| 'v' | triangle_down marker |
| '^' | triangle_up marker |
| '<' | triangle_left marker |
| '>' | triangle_right marker |
| '1' | tri_down marker |
| '2' | tri_up marker |
| '3' | tri_left marker |
| '4' | tri_right marker |
| 's' | square marker |
| 'p' | pentagon marker |
| '*' | star marker |
| 'h' | hexagon1 marker |
| 'H' | hexagon2 marker |
| '+' | plus marker |
| 'x' | x marker |
| 'D' | diamond marker |
| 'd' | thin_diamond marker |
| ' | ' |
| '_' | hline marker |
The following color abbreviations are supported:
| character | color |
|---|---|
| ‘b’ | blue |
| ‘g’ | green |
| ‘r’ | red |
| ‘c’ | cyan |
| ‘m’ | magenta |
| ‘y’ | yellow |
| ‘k’ | black |
| ‘w’ | white |
演示
plt.axis([0,5,0,20]) # [xmin,xmax,ymin,ymax]對應軸的范圍
plt.title('My first plot') # 圖名
plt.plot([1,2,3,4], [1,4,9,16], 'ro') # 圖上的點,最后一個參數為顯示的模式
Out[5]: [<matplotlib.lines.Line2D at 0x24e0a5bc2b0>]
plt.show() # 展示圖片

In [11]: t = np.arange(0, 2.5, 0.1)
...: y1 = list(map(math.sin, math.pi*t))
...: y2 = list(map(math.sin, math.pi*t + math.pi/2))
...: y3 = list(map(math.sin, math.pi*t - math.pi/2))
...:
In [12]: plt.plot(t, y1, 'b*', t, y2, 'g^', t, y3, 'ys')
Out[12]:
[<matplotlib.lines.Line2D at 0x24e0a8469b0>,
<matplotlib.lines.Line2D at 0x24e0a58de48>,
<matplotlib.lines.Line2D at 0x24e0a846b38>]
In [13]: plt.show()

In [14]: plt.plot(t,y1,'b--',t,y2,'g',t,y3,'r-.')
Out[14]:
[<matplotlib.lines.Line2D at 0x24e0a8b49e8>,
<matplotlib.lines.Line2D at 0x24e0a8b4c88>,
<matplotlib.lines.Line2D at 0x24e0a8b95c0>]
In [15]: plt.show()

3. 處理多個Figure和Axes對象
subplot(nrows, ncols, plot_number)
In [19]: plt.subplot(2,1,1)
...: plt.plot(t,y1,'b-.')
...: plt.subplot(2,1,2)
...: plt.plot(t,y2,'r--')
...:
Out[19]: [<matplotlib.lines.Line2D at 0x24e0b8f47b8>]
In [20]: plt.show()

In [30]: plt.subplot(2,1,1)
...: plt.plot(t,y1,'b-.')
...: plt.subplot(2,1,2)
...: plt.plot(t,y2,'r--')
...:
Out[30]: [<matplotlib.lines.Line2D at 0x24e0bb9fc88>]
In [31]: plt.show()

4. 添加更多元素
4.1. 添加文本
添加標題:title()
添加軸標簽:xlabel()和ylabel()
在圖形的坐標添加文本:text(x, y, string, fontdict=None, **kwargs),分別表示坐標和字符串以及一些關鍵字參數。
還可以添加LaTeX表達式,繪制邊框等。
In [40]: plt.axis([0,5,0,20])
...: plt.title('_Kazusa', fontsize=20, fontname='Times New Roman')
...: plt.xlabel('x_axis', color='orange')
...: plt.ylabel('y_axis', color='gray')
...: plt.text(1, 1.5, 'A')
...: plt.text(2, 4.5, 'B')
...: plt.text(3, 9.5, 'C')
...: plt.text(4, 16.5, 'D')
...: plt.text(0.5, 15, r'$y=x^2$', fontsize=20, bbox={'facecolor':'yellow','alpha':0.2})
...: plt.plot([1,2,3,4],[1,4,9,16],'ro')
...:
Out[40]: [<matplotlib.lines.Line2D at 0x24e0bf03240>]
In [41]: plt.show()

4.2. 其他元素
網格:grid(True) 表示顯示網格
圖例:matplotlib.pyplot.legend(*args, **kwargs)
圖例的位置參數:
loc : int or string or pair of floats, default: ‘upper right’
The location of the legend. Possible codes are:
| Location String | Location Code |
|---|---|
| ‘best’ | 0 |
| ‘upper right’ | 1 |
| ‘upper left’ | 2 |
| ‘lower left’ | 3 |
| ‘lower right’ | 4 |
| ‘right’ | 5 |
| ‘center left’ | 6 |
| ‘center right’ | 7 |
| ‘lower center’ | 8 |
| ‘upper center’ | 9 |
| ‘center’ | 10 |
Alternatively can be a 2-tuple giving x, y of the lower-left corner of the legend in axes coordinates (in which case bbox_to_anchor will be ignored).
In [44]: plt.axis([0,5,0,20])
...: plt.title('_Kazusa', fontsize=20, fontname='Times New Roman')
...: plt.xlabel('x_axis', color='orange')
...: plt.ylabel('y_axis', color='gray')
...: plt.text(1, 1.5, 'A')
...: plt.text(2, 4.5, 'B')
...: plt.text(3, 9.5, 'C')
...: plt.text(4, 16.5, 'D')
...: plt.text(0.5, 10, r'$y=x^2$', fontsize=20, bbox={'facecolor':'yellow','alpha':0.2})
...: plt.plot([1,2,3,4],[1,4,9,16],'ro')
...: plt.grid(True)
...: plt.plot([1,2,3,4],[0.6,2.3,14.5,15.8], 'g^')
...: plt.plot([1,2,3,4],[0.2,9.7,11.6,13.9],'b*')
...: plt.legend(['First series', 'Sencond series', 'Third series'], loc=0)
...:
Out[44]: <matplotlib.legend.Legend at 0x24e0c02a630>
In [45]: plt.show()

5. 保存
%save mycode 44
# %save魔術命令后,跟着文件名和代碼對於的命令提示符號碼。例如上面In [44]: plt.axis([0,5,0,20])號碼就是44,運行之后會在工作目錄生成'mycode.py'文件,還可以是'數字-數字',即保存從一個行數到另一個行數的代碼
ipython qtconsole -m mycode.py
#可以打開之前的代碼
%load mycode.py
#可以加載所有代碼
%run mycode.py
#可以運行代碼
#保存圖片的話,可以在生成圖標的一系列命令之后加上savefig()函數把圖標保存為PNG格式。
#在保存圖像命令之前不要使用plt.show()否則會得到空白圖像
In [30]: plt.subplot(2,1,1)
...: plt.plot(t,y1,'b-.')
...: plt.subplot(2,1,2)
...: plt.plot(t,y2,'r--')
...: plt.savefig('pic.png')
6. 線形圖
替換坐標軸的刻度的標簽:xticks()和yticks()。傳入的參數第一個是存儲刻度的位置的列表,第二個是存儲刻度的標簽的列表。要正確顯示標簽,要使用含有LaTeX表達式的字符串。
顯示笛卡爾坐標軸:首先用gca()函數獲取Axes對象。通過這個對象,指定每條邊的位置:上下左右,可選擇組成圖形邊框的每條邊。使用set_color()函數,設置顏色為'none'(這里我不刪除而是換了個顏色方便確認位置),刪除根坐標軸不符合的邊(右上)。用set_positon()函數移動根x軸和y軸相符的邊框,使其穿過原點(0,0)。
annotate()函數可以添加注釋。第一個參數為含有LaTeX表達式、要在圖形中顯示的字符串;隨后是關鍵字參數。文本注釋跟它所解釋的數據點之間的距離用xytext關鍵字參數指定,用曲線箭頭將其表示出來。箭頭的屬性由arrowprops關鍵字參數指定。
In [57]: x = np.arange(-2*np.pi, 2*np.pi, 0.01)
...: y1 = np.sin(3*x)/x
...: y2 = np.sin(2*x)/x
...: y3 = np.sin(x)/x
...: plt.plot(x,y1,color='y')
...: plt.plot(x,y2,color='r')
...: plt.plot(x,y3,color='k')
...: plt.xticks([-2*np.pi, -np.pi, 0, np.pi, 2 * np.pi], [r'$-2\pi$', r'$-\pi$', r'$0$', r'$+\pi$', r'$+2\pi$'])
...: plt.yticks([-1, 0, +1, +2, +3], [r'$-1$', r'$0$', r'$+1$', r'$+2$', r'$+3$'])
...: # 設置坐標軸標簽
...: plt.annotate(r'$\lim_{x\to 0}\frac{\sin(x)}{x}=1$', xy=[0,1], xycoords='data', xytext=[30,30], fontsize=18, textcoords='offset points', arrowprops=dict(arrowstyle="->",connectionstyle="arc3,rad=.2")) # 設置注釋
...:
...: ax = plt.gca()
...: ax.spines['right'].set_color('r')
...: ax.spines['top'].set_color('b')
...: ax.xaxis.set_ticks_position('bottom')
...: ax.spines['bottom'].set_position(('data',0))
...: ax.yaxis.set_ticks_position('left')
...: ax.spines['left'].set_position(('data',0))
...: ax.spines['bottom'].set_color('g')
...: ax.spines['left'].set_color('k') # 設置笛卡爾坐標軸
...:
In [58]: plt.show()

為pandas數據結構繪制線形圖##
把DataFrame作為參數傳入plot()函數,就可以得到多序列線形圖。
In [60]: data = {'series1':[1,3,4,3,5], 'series2':[2,4,5,2,4], 'series3':[5,4,4,1,5]}
...: df = pd.DataFrame(data)
...: x = np.arange(5)
...: plt.axis([0,6,0,6])
...: plt.plot(x,df)
...: plt.legend(data, loc=0)
...:
Out[60]: <matplotlib.legend.Legend at 0x24e0dbda668>
In [61]: plt.show()


7. 直方圖
hist()可以用於繪制直方圖。
In [4]: array = np.random.randint(0, 50, 50)
In [5]: array
Out[5]:
array([43, 1, 16, 9, 22, 15, 1, 12, 9, 25, 37, 47, 31, 15, 25, 43, 3,
28, 21, 23, 11, 10, 14, 27, 10, 19, 40, 44, 26, 49, 13, 35, 19, 48,
7, 21, 37, 47, 2, 4, 15, 20, 47, 11, 2, 49, 31, 31, 1, 46])
In [8]: n, bins, patches = plt.hist(array, bins=10) # hist()第二個參數便是划分的面元個數,n表示每個面元有幾個數字,bins表示面元的范圍,patches表示每個長條
In [10]: n
Out[10]: array([ 7., 5., 8., 4., 4., 5., 3., 3., 4., 7.])
In [11]: bins
Out[11]:
array([ 1. , 5.8, 10.6, 15.4, 20.2, 25. , 29.8, 34.6, 39.4,
44.2, 49. ])
In [13]: for patch in patches:
...: print(patch)
...:
Rectangle(1,0;4.8x7)
Rectangle(5.8,0;4.8x5)
Rectangle(10.6,0;4.8x8)
Rectangle(15.4,0;4.8x4)
Rectangle(20.2,0;4.8x4)
Rectangle(25,0;4.8x5)
Rectangle(29.8,0;4.8x3)
Rectangle(34.6,0;4.8x3)
Rectangle(39.4,0;4.8x4)
Rectangle(44.2,0;4.8x7)
In [9]: plt.show()

8. 條狀圖
bar()函數可以生成垂直條狀圖
barh()函數可以生成水平條狀圖,設置的時候坐標軸參數和垂直條狀圖相反,其他都是一樣的。
8.1 普通條狀圖
In [24]: index = np.arange(5)
...: values = [5,7,3,4,6]
...: plt.bar(index, values)
...: plt.title('_Kazusa')
...: plt.xticks(index,['A','B','C','D','E'])
...: plt.legend('permutation', loc = 0)
...:
Out[24]: <matplotlib.legend.Legend at 0x22abd7a7a20>
In [25]: plt.show()

8.2 多序列條狀圖
In [34]: index = np.arange(5)
...: val1 = [5,7,3,4,6]
...: val2 = [6,6,4,5,7]
...: val3 = [5,6,5,4,6]
...: gap = 0.31 # 把每個類別占的空間(總空間為1)分成多個部分,例如這里有三個,因為要增加一點空間區分相鄰的類別,因此取0.31
...: plt.axis([0,5,0,8])
...: plt.title('_Kazusa')
...: plt.bar(index+0.2, val1, gap, color='b')
...: plt.bar(index+gap+0.2, val2, gap, color='y')
...: plt.bar(index+2*gap+0.2, val3, gap, color='k')
...: plt.xticks(index+gap+0.2, ['A','B','C','D','E']) # index+gap即標簽偏移gap的距離
...:
Out[34]:
([<matplotlib.axis.XTick at 0x22abd72a6d8>,
<matplotlib.axis.XTick at 0x22abd93fba8>,
<matplotlib.axis.XTick at 0x22abd9f95f8>,
<matplotlib.axis.XTick at 0x22abda5e400>,
<matplotlib.axis.XTick at 0x22abda5edd8>],
<a list of 5 Text xticklabel objects>)
In [35]: plt.show()

8.3 對序列堆積條狀圖
有時候需要表示總和是由幾個條狀圖相加得到,因此堆積圖表示比較合適。
使用bar()的時候添加參數bottom= 來確定下面是什么。
In [41]: arr1 = np.array([3,4,5,3])
...: arr2 = np.array([1,2,2,5])
...: arr3 = np.array([2,3,3,4])
...: index = np.arange(4)
...: plt.axis([0,4,0,15])
...: plt.title('_Kazusa')
...: plt.bar(index + 0.5, arr1, color='r')
...: plt.bar(index + 0.5, arr2, color='b', bottom=arr1)
...: plt.bar(index + 0.5, arr3, color='y', bottom=(arr1+arr2))
...: plt.xticks(index + 0.5, ['A','B','C','D','E'])
...:
Out[41]:
([<matplotlib.axis.XTick at 0x22abd953a90>,
<matplotlib.axis.XTick at 0x22abda95550>,
<matplotlib.axis.XTick at 0x22abdb99320>,
<matplotlib.axis.XTick at 0x22abdbff630>],
<a list of 4 Text xticklabel objects>)
In [42]: plt.show()


8.4 為DataFrame繪制條狀圖
In [47]: data = {'arr1':[1,3,4,3,5], 'arr2':[2,4,5,2,4], 'arr3':[1,3,5,1,2]}
...: df = pd.DataFrame(data)
...: df.plot(kind='bar') # 若要堆積圖,變成 df.plot(kind='bar', stacked=True)
...:
Out[47]: <matplotlib.axes._subplots.AxesSubplot at 0x22abdcb3cf8>
In [48]: plt.show()

9. 餅圖
pie()函數可以制作餅圖
In [51]: labels = ['A','B','C','D'] # 標簽
...: values = [10,30,45,15] # 數值
...: colors = ['yellow', 'green', 'red', 'orange'] # 顏色
...: explode = [0.3, 0, 0, 0] # 突出顯示,數值0~1
...: plt.title('_Kazusa')
...: plt.pie(values, labels=labels, colors=colors, explode=explode, startangle=90, shadow=True, autopct='%1.1f%%') # shadow表示陰影, autopct表示顯示百分比, startangle表示餅旋轉的角度
...: plt.axis('equal')
...:
Out[51]:
(-1.1007797083302826,
1.1163737124158366,
-1.1306395753855039,
1.4003625034945653)
In [52]: plt.show()

10. 等值線圖
由一圈圈封閉的曲線組成的等值線圖表示三維結構的表面,其中封閉的曲線表示的是一個個處於同一層級或z值相同的數據點。
contour()函數可以生成等值線圖。
In [57]: dx = 0.01; dy = 0.01
...: x = np.arange(-2.0, 2.0, dx)
...: y = np.arange(-2.0, 2.0, dy)
...: X, Y = np.meshgrid(x, y) # 這里meshigrid(x,y)的作用是產生一個以向量x為行,向量y為列的矩陣,而x是從-2開始到2,每間隔dx記下一個數據,並把這些數據集成矩陣X;同理y則是從-2到2,每間隔dy記下一個數據,並集成矩陣Y
...: def f(x,y): # 生成z的函數
...: return (1 - y**5 + x**5) * np.exp(-x**2 - y**2)
...: C = plt.contour(X, Y, f(X,Y), 8, colors='black') # 8表示分層的密集程度,越小越稀疏,colors表示最開始是什么顏色
...: plt.contourf(X, Y, f(X,Y), 8) # 使用顏色,8的意義同上
...: plt.clabel(C, inline=1, contsize=10) # 生成等值線的標簽
...: plt.colorbar() # 側邊的顏色說明
...:
Out[57]: <matplotlib.colorbar.Colorbar at 0x22abf289470>
In [58]: plt.show()

11. 3D圖
3D圖的Axes對象要替換為Axes3D對象。
from mpl_toolkits.mplot3d import Axes3D
11.1. 3D曲面
plot_surface(X, Y, Z, *args, **kwargs)可以顯示面
| Argument | Description |
|---|---|
| X, Y, Z | Data values as 2D arrays |
| rstride | Array row stride (step size) |
| cstride | Array column stride (step size) |
| rcount | Use at most this many rows, defaults to 50 |
| ccount | Use at most this many columns, defaults to 50 |
| color | Color of the surface patches |
| cmap | A colormap for the surface patches. |
| facecolors | Face colors for the individual patches |
| norm | An instance of Normalize to map values to colors |
| vmin | Minimum value to map |
| vmax | Maximum value to map |
| shade | Whether to shade the facecolors |
In [9]: fig = plt.figure()
...: ax = Axes3D(fig)
...: X = np.arange(-2, 2, 0.1)
...: Y = np.arange(-2, 2, 0.1)
...: X, Y = np.meshgrid(X, Y)
...: def f(x,y):
...: return (1 - y ** 5 + x ** 5) * np.exp(-x ** 2 - y ** 2)
...: ax.plot_surface(X, Y, f(X,Y), rstride=1, cstride=1) # rstide/cstride表示 行/列數組的跨度
...: ax.view_init(elev=30,azim=125) # elev指定從哪個高度查看曲面,azim指定曲面旋轉的角度
...:
In [10]: pt.show()

11.2. 3D散點圖
Axes3D.scatter(xs, ys, zs=0, zdir='z', s=20, c=None, depthshade=True, *args, **kwargs)可以使用散點圖
| Argument | Description |
|---|---|
| xs, ys | Positions of data points. |
| zs | Either an array of the same length as xs and ys or a single value to place all points in the same plane. Default is 0. |
| zdir | Which direction to use as z (‘x’, ‘y’ or ‘z’) when plotting a 2D set. |
| s | Size in points^2. It is a scalar or an array of the same length as x and y. |
| c | A color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). |
| depthshade | Whether or not to shade the scatter markers to give the appearance of depth. Default is True. |
In [16]: x1 = np.random.randint(30, 40, 100)
...: y1 = np.random.randint(30, 40, 100)
...: z1 = np.random.randint(10, 20, 100)
...: x2 = np.random.randint(50, 60, 100)
...: y2 = np.random.randint(50, 60, 100)
...: z2 = np.random.randint(10, 20, 100)
...: x3 = np.random.randint(30, 40, 100)
...: y3 = np.random.randint(30, 40, 100)
...: z3 = np.random.randint(40, 50, 100)
...: fig = plt.figure()
...: ax = Axes3D(fig)
...: ax.scatter(x1, y1, z1)
...: ax.scatter(x2, y2, z2, c = 'r', marker = '^')
...: ax.scatter(x3, y3, z3, c = 'y', marker = '*')
...: ax.set_xlabel('X axis')
...: ax.set_ylabel('Y axis')
...: ax.set_zlabel('Z axis')
...:
Out[16]: <matplotlib.text.Text at 0x1b0218fda90>
In [17]: plt.show()

11.3. 3D條狀圖
bar()函數
Axes3D.bar(left, height, zs=0, zdir='z', *args, **kwargs)
| Argument | Description |
|---|---|
| left | The x coordinates of the left sides of the bars. |
| height | The height of the bars. |
| zs | Z coordinate of bars, if one value is specified they will all be placed at the same z. |
| zdir | Which direction to use as z (‘x’, ‘y’ or ‘z’) when plotting a 2D set. |
In [22]: x = np.arange(5)
...: y1 = np.random.randint(0, 10, 5)
...: y2 = y1 + np.random.randint(0, 3, 5)
...: y3 = y2 + np.random.randint(0, 3, 5)
...: y4 = y3 + np.random.randint(0, 3, 5)
...: y5 = y4 + np.random.randint(0, 3, 5)
...: clr = ['yellow', 'red', 'blue', 'black', 'green']
...: fig = plt.figure()
...: ax = Axes3D(fig)
...: ax.bar(x, y1, 0, zdir = 'y', color = clr)
...: ax.bar(x, y2, 10, zdir = 'y', color = clr)
...: ax.bar(x, y3, 20, zdir = 'y', color = clr)
...: ax.bar(x, y4, 30, zdir = 'y', color = clr)
...: ax.bar(x, y5, 40, zdir = 'y', color = clr)
...: ax.set_xlabel('x Axis')
...: ax.set_ylabel('y Axis')
...: ax.set_zlabel('z Axis')
...: ax.view_init(elev=40)
...:
In [23]: plt.show()

12. 多面板圖形
12.1. 在其他子圖中顯示子圖
把主Axes對象(主圖表)跟放置另一個Axes對象實例的框架分開。用figure()函數取到Figure對象,用add_axes()函數在它上面定義兩個Axes對象。
add_axes(*args, **kwargs)
rect = l,b,w,h # (分別是左邊界,下邊界,寬,高)
fig.add_axes(rect)
In [28]: fig = plt.figure()
...: ax = fig.add_axes([0.1,0.1,0.8,0.8])
...: inner_ax = fig.add_axes([0.6,0.6,0.25,0.25])
...: x1 = np.arange(10)
...: y1 = np.array([1,2,7,1,5,2,4,2,3,1])
...: x2 = np.arange(10)
...: y2 = np.array([1,2,3,4,6,4,3,4,5,1])
...: ax.plot(x1,y1)
...: inner_ax.plot(x2,y2)
...:
Out[28]: [<matplotlib.lines.Line2D at 0x1b022ac94a8>]
In [29]: plt.show()

12.2. 子圖網格
class matplotlib.gridspec.GridSpec(nrows, ncols, left=None, bottom=None, right=None, top=None, wspace=None, hspace=None, width_ratios=None, height_ratios=None)
add_subplot(*args, **kwargs)
In [30]: gs = plt.GridSpec(3,3) # 分成多少塊
...: fig = plt.figure(figsize=(8,8)) # 指定圖的尺寸
...: x1 = np.array([1,3,2,5])
...: y1 = np.array([4,3,7,2])
...: x2 = np.arange(5)
...: y2 = np.array([3,2,4,6,4])
# 可以看做分作一個3*3的格子,每次給一個表分配格子,[row,col],[0,0]表示左上角
...: p1 = fig.add_subplot(gs[1,:2])
...: p1.plot(x1, y1, 'r')
...: p2 = fig.add_subplot(gs[0,:2])
...: p2.bar(x2, y2)
...: p3 = fig.add_subplot(gs[2,0])
...: p3.barh(x2, y2, color='b')
...: p4 = fig.add_subplot(gs[:2,2])
...: p4.plot(x2, y2, 'k')
...: p5 = fig.add_subplot(gs[2,1:])
...: p5.plot(x1, y1, 'b^', x2, y2, 'yo')
...:
Out[30]:
[<matplotlib.lines.Line2D at 0x1b022c8a940>,
<matplotlib.lines.Line2D at 0x1b022cdc4a8>]
In [32]: plt.show()


