對於Python數據可視化庫,matplotlib 已經成為事實上的數據可視化方面最主要的庫,此外還有很多其他庫,例如vispy,bokeh, seaborn,pyga,folium 和 networkx,這些庫有些是構建在 matplotlib 之上,還有些有其他一些功能。
目錄
- matplotlib
- 基本函數
- 中文亂碼
- plot:線性圖
- bar:柱狀圖
- barh:水平柱狀圖
- pie:餅圖
- scatter:散點圖
- hist:直方圖
- stackplot:面積圖
- subplot:子圖布局
- GridSpec:網格布局
matplotlib
matplotlib 是一個基於 Python 的 2D 繪圖庫,其可以在跨平台的在各種硬拷貝格式和交互式環境中繪制出高圖形。Matplotlib 能夠創建多數類型的圖表,如條形圖,散點圖,條形圖,餅圖,堆疊圖,3D 圖和地圖圖表。
%matplotlib 命令可以在當前的 Notebook 中啟用繪圖。Matlibplot 提供了多種繪圖 UI ,可進行如下分類 :
- 彈出窗口和交互界面: %matplotlib qt 和 %matplot tk
- 非交互式內聯繪圖: %matplotlib inline
- 交互式內聯繪圖: %matplotlib notebook-->別用這個,它會讓開關變得困難。
安裝Matplotlib命令:pip install matplotlib
基本函數
legend:增加圖例(線的標題) ,格式:plt.legend(handles=(line1, line2, line3),labels=('label1', 'label2', 'label3'),loc='upper right'), 見如下示例代碼
1 ln1, = plt.plot(x_data, y_data, color = 'red', linewidth = 2.0, linestyle = '--') 2 ln2, = plt.plot(x_data, y_data2, color = 'blue', linewidth = 3.0, linestyle = '-.') 3 plt.legend(handles=[ln2, ln1], labels=['Android基礎', 'Java基礎'], loc='lower right')
loc參數值:
- 'best':自動選擇最佳位置
- 'upper right':將圖例放在右上角。
- 'upper left':將圖例放在左上角。
- 'lower left':將圖例放在左下角。
- 'lower right':將圖例放在右下角。
- 'right':將圖例放在右邊。
- 'center left':將圖例放在左邊居中的位置。
- 'center right':將圖例放在右邊居中的位置。
- 'lower center':將圖例放在底部居中的位置。
- 'upper center':將圖例放在頂部居中的位置。
- 'center':將圖例放在中心。
figure:新建一個畫布,格式:figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True)
- num:圖像編號或名稱,數字為編號 ,字符串為名稱
- figsize:指定figure的寬和高,單位為英寸;
- dpi:指定繪圖對象的分辨率,即每英寸多少個像素,缺省值為80;1英寸等於2.5cm,A4紙是 21*30cm的紙張
- frameon:是否顯示邊框
spines:在matplotlib的圖中,默認有四個軸,兩個橫軸和兩個豎軸,可以通過ax = plt.gca()方法獲取,gca是‘get current axes’的縮寫,獲取圖像的軸,總共有四個軸 top、bottom、left、right
- axis指定要用的軸:由於axes會獲取到四個軸,而我們只需要兩個軸,所以我們需要把另外兩個軸隱藏,把頂部和右邊軸的顏色設置為none, 如:plt.gca().spines['top'].set_color('none')
- 移動軸到指定位置:ax.spines[‘bottom’]獲取底部的軸,通過 set_position 方法,設置底部軸的位置,例如:ax.spines[‘bottom’].set_position((‘data’,0)) 表示設置底部軸移動到豎軸的0坐標位置,設置軸設置的方法相同
示例代碼:

1 import matplotlib.pyplot as plt 2
3 fig = plt.figure(figsize=(4, 3), frameon=True, facecolor='r') 4 ax = fig.add_subplot(1, 1, 1) 5 ax.spines['top'].set_color = 'none'
6 ax.spines['right'].set_color = 'none'
7 ax.spines['left'].set_position(('data', 0)) 8 ax.spines['bottom'].set_position(('data', 0)) 9 plt.show()
效果圖:
中文亂碼
- 問題描述:matplotlib繪制圖像在顯示中文時候,中文會變成小方格子。其實plotlib是支持中文編碼的,造成這個現象的原因是,matplotlib庫的配置信息里面沒有中文字體的相關信息
- 解決方案:在python腳本中動態設置 matplotlibrc,這樣就避免了更改配置文件的麻煩,方便靈活,更改了字體導致顯示不出負號,將配署文件中 axes.unicode minus :True 修改為 Falsest 就可以了,代碼如下:
1 from pylab import mpl 2
3 mpl.rcParams['font.sans-serif'] = 'FangSong' # 指定默認字體
4 mpl.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負號'-'顯示為方塊的問題
Windows的字體對應名稱如下
- 黑體:SimHei
- 微軟雅黑:Microsoft YaHei
- 微軟正黑體:Microsoft JhengHei
- 新宋體:NSimSun
- 新細明體:PMingLiU
- 標楷體:DFKai-SB
- 仿宋:FangSong
- 楷體:KaiTi
- 仿宋_GB2312: FangSong_GB2312
- 楷體_GB2312: KaiTi_GB2312
plot:線性圖
格式:plt.plot(x,y,format_string,**kwargs)
- x軸數據,y軸數據,format_string控制曲線的格式字串
- format_string:由顏色字符,風格字符,和標記字符。具體形式 fmt = '[color][marker][line]' ,fmt接收的是每個屬性的單個字母縮寫,見如下代碼:
- plot(x,y2,color='green', marker='o', linestyle='dashed', linewidth=1, markersize=6)
- plot(x,y3,color='#900302',marker='+',linestyle='-')
- 還可包含有其它的屬性,如:markerfacecolor:標記顏色 、markersize: 標記大小 等等
示例:

1 import matplotlib.pyplot as plt 2 from pylab import mpl 3
4 mpl.rcParams['font.sans-serif'] = 'FangSong' # 指定默認字體
5 mpl.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負號'-'顯示為方塊的問題
6
7 year = ['1950', '1960', '1970', '1980', '1990', '2000', '2010'] 8 gdp = [300.2, 543.3, 1075.9, 2862.5, 5979.6, 10298.7, 14958.3] 9 y_data = [100, 200, 300, 400, 500, 600, 700] 10
11
12 def draw_plot(): 13 # plt.plot(year, gdp, 'go-', year, y_data, 'rp:')
14 plt.plot(year, gdp, 'go-', label='gdp') 15 plt.plot(year, y_data, 'rp:', label='second line') 16 plt.title("plot 線圖demo") 17 plt.xlabel('年度') 18 plt.ylabel('gdp') 19 plt.legend() #生成默認圖例
20 plt.show()
效果圖:
bar:柱狀圖
格式:bar(left, height, width, alpha=1, width=0.8, color=, edgecolor=, label=, lw=3)
- left:x軸的位置序列,一般采用arange函數產生一個序列;
- height:y軸的數值序列,也就是柱形圖的高度,一般就是我們需要展示的數據;
- width:柱形圖的寬度,一般這是為1即可;
- alpha:透明度
- width:為柱形圖的寬度,一般這是為0.8即可;
- color或facecolor:柱形圖填充的顏色;
- edgecolor:圖形邊緣顏色
- label:解釋每個圖像代表的含義
- linewidth or linewidths or lw:邊緣or線的寬度
示例

1 def draw_bar(): 2 plt.bar(x=year, height=gdp, width=0.4, label='gdp', color='green') 3 plt.bar(x=year, height=y_data, width=0.4, label='secend', color='red') 4 # 在柱狀圖上顯示具體數值, ha參數控制水平對齊方式, va控制垂直對齊方式
5 for x, y in enumerate(y_data): 6 plt.text(x, y - 400, '%s' % y, ha='center', va='bottom') 7 for x, y in enumerate(gdp): 8 plt.text(x, y + 400, '%s' % y, ha='center', va='top') 9
10 plt.title("bar 條形圖") 11 plt.xlabel('年度') 12 plt.ylabel('gdp') 13 plt.legend() 14 plt.show()
效果圖:
使用 bar() 函數繪制柱狀圖時,默認不會在柱狀圖上顯示具體的數值。為了能在柱狀圖上顯示具體的數值,程序可以調用 text() 函數在數據圖上輸出文字,增加如下代碼:1for x, y in enumerate(y_data):
1 for x, y in enumerate(y_data): 2 plt.text(x, y - 400, '%s' % y, ha='center', va='bottom') 3 for x, y in enumerate(gdp): 4 plt.text(x, y + 400, '%s' % y, ha='center', va='top')
- 在使用 text() 函數輸出文字時,該函數的前兩個參數控制輸出文字的 X、Y 坐標,第三個參數則控制輸出的內容。其中 va 參數控制文字的垂直對齊方式,ha 參數控制文字的水平對齊方式。
- 對於上面的代碼,由於 X 軸數據是一個字符串列表,因此 X 軸實際上是以列表元素的索引作為刻度值的。因此,當程序指定輸出文字的 X 坐標為 0 時,表明將該文字輸出到第一個條柱處;對於 Y 坐標而言,條柱的數值正好在條柱高度所在處,如果指定 Y 坐標為條柱的數值 +400,就是控制將文字輸出到條柱略上一點的位置。
效果圖:
如上圖 所示的顯示效果來看柱狀圖重疊,為了實現條柱井列顯示的效果,首先分析條柱重疊在一起的原因。使用 Matplotlib 繪制柱狀圖時同樣也需要 X 軸數據,本程序的 X 軸數據是元素為字符串的 list 列表,因此程序實際上使用各字符串的索引作為 X 軸數據。比如 '1950' 字符串位於列表的第一個位置,因此代表該條柱的數據就被繪制在 X 軸的刻度值1處(由於兩個柱狀圖使用了相同的 X 軸數據,因此它們的條柱完全重合在一起)。為了將多個柱狀圖的條柱並列顯示,程序需要為這些柱狀圖重新計算不同的 X 軸數據。為了精確控制條柱的寬度,程序可以在調用 bar() 函數時傳入 width 參數,這樣可以更好地計算條柱的並列方式。
示例 :

1 def draw_bar2(): 2 barwidth=0.4
3 plt.bar(x=range(len(year)), height=gdp, width=0.4, label='gdp', color='green') 4 plt.bar(x=np.arange(len(year)) + barwidth, height=y_data, width=0.4, label='secend', color='red') 5 # 在柱狀圖上顯示具體數值, ha參數控制水平對齊方式, va控制垂直對齊方式
6 for x, y in enumerate(gdp): 7 plt.text(x, y + 400, '%s' % y, ha='center', va='top') 8 for x, y in enumerate(y_data): 9 plt.text(x + barwidth, y + 400, '%s' % y, ha='center', va='top') 10
11 plt.title("bar 條形圖") 12 plt.xlabel('年度') 13 plt.ylabel('gdp') 14 plt.legend() 15 plt.show()
效果圖:
運行上面程序,將會發現該柱狀圖的 X 軸的刻度值變成 0、1、2 等值,不再顯示年份。為了讓柱狀圖的 X 軸的刻度值顯示年份,程序可以調用 xticks() 函數重新設置 X 軸的刻度值,如下:
- plt.xticks(np.arange(len(year)) + barwidth/2, year)
- bar_width/2: 這些刻度值將被恰好添加在兩個條柱之間
希望兩個條柱之間有一點縫隙,那么程序只要對第二個條柱的 X 軸數據略做修改即可,完整代碼如下:

1 def draw_bar2(): 2 barwidth=0.4
3 plt.bar(x=range(len(year)), height=gdp, width=barwidth, label='gdp', color='green') 4 plt.bar(x=np.arange(len(year)) + barwidth + 0.01, height=y_data, width=barwidth, label='secend', color='red') 5 # 在柱狀圖上顯示具體數值, ha參數控制水平對齊方式, va控制垂直對齊方式
6 for x, y in enumerate(gdp): 7 plt.text(x, y + 400, '%s' % y, ha='center', va='top') 8 for x, y in enumerate(y_data): 9 plt.text(x + barwidth + 0.01, y + 400, '%s' % y, ha='center', va='top') 10
11 #X軸添加刻度
12 plt.xticks(np.arange(len(year)) + barwidth/2 + 0.01, year) 13 plt.title("bar 條形圖") 14 plt.xlabel('年度') 15 plt.ylabel('gdp') 16 plt.legend() 17 plt.show()
效果圖:
barh:水平柱狀圖
barh() 函數的用法與 bar() 函數的用法基本一樣,只是在調用 barh() 函數時使用 y參數傳入 Y 軸數據,使用 width 參數傳入代表條柱寬度的數據。
示例:

1 def draw_barh(): 2 barwidth = 0.4
3 plt.barh(y=range(len(year)), width=gdp, height=barwidth, label='gdp', color='green') 4 plt.barh(y=np.arange(len(year)) + barwidth + 0.01, width=y_data, height=barwidth, label='secend', color='red') 5 # 在柱狀圖上顯示具體數值, ha參數控制水平對齊方式, va控制垂直對齊方式
6 for y, x in enumerate(gdp): 7 plt.text(x + 1000, y + barwidth/2, '%s' % x, ha='center', va='bottom') 8 for y, x in enumerate(y_data): 9 plt.text(x + 1400, y + barwidth/2 - 0.01, '%s' % x, ha='center', va='top') 10
11 # y軸添加刻度
12 plt.yticks(np.arange(len(year)) + barwidth / 2 + 0.01, year) 13 plt.title("barh 水平柱狀圖") 14 plt.xlabel('gdp') 15 plt.ylabel('年度') 16 plt.legend() 17 plt.show()
效果圖:
pie:餅圖
格式:pie(x, explode=None, labels=None, colors=('b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'), autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, counterclock=True, wedgeprops=None, textprops=None, center = (0, 0), frame = False )
- 創建餅圖最重要的兩個參數就是 x 和 labels,其中 x 指定餅圖各部分的數值,labels 則指定各部分對應的標簽
- 通常,餅圖用於顯示部分對於整體的情況,通常以%為單位。 幸運的是,Matplotlib 會處理切片大小以及一切事情,我們只需要提供數值。
- x:繪圖數據
- explode:突出顯示,如將第4個數據顯示:explode = [0, 0, 0, 0.3, 0, 0, 0, 0, 0, 0, 0]
- labels:顯示標簽
- autopct:設置百分比的格式,如保留3位小數:autopct='%.3f%%'
- pctdistance:置百分比標簽與圓心的距離,如:pctdistance=0.8
- labeldistance:設置標簽與圓心的距離,如:startangle = 180
- startangle:設置餅圖的初始角度, 如:startangle = 180
- center : 設置餅圖的圓心(相當於X軸和Y軸的范圍),如:center = (4, 4)
- radius :設置餅圖的半徑(相當於X軸和Y軸的范圍),如:radius = 3.8
- counterclock :是否逆時針,如這里設置為順時針方向:counterclock = False,
- wedgeprops:設置餅圖內外邊界的屬性值,如:wedgeprops = {'linewidth': 1, 'edgecolor':'green'}
- textprops:設置文本標簽的屬性值,如:textprops = {'fontsize':12, 'color':'black'}
- frame :是否顯示餅圖的圓圈,如此處設為顯示:frame = 1
示例

1 def draw_pie(): 2 plt.pie(x=gdp, 3 labels=year, 4 autopct='%.3f%%', 5 explode=[0, 0, 0, 0.03, 0, 0, 0]) 6
7 plt.title("pie 圖") 8 plt.show()
效果:
scatter:散點圖
格式:scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, hold=None, data=None, **kwargs)
- x, y:指 x 軸、y軸數據
- s:指定散點的大小(設置點半徑),如:s=50
- c:指定散點的顏色。如:c='red'
- alpha:指定散點的透明度。如:alpha = 0.5
- marker:指定散點的圖形樣式,見最上面標記字符圖,如:marker='p'
示例:

1 def draw_catter(): 2 plt.scatter(x=year, y=gdp, c='red', marker='*', s=100) 3
4 plt.title("catter 散點圖") 5 plt.show()
效果:
hist:直方圖
柱狀圖與直方圖:
- 柱狀圖是用條形的長度表示各類別頻數的多少,其寬度(表示類別)則是固定的;
- 直方圖是用面積表示各組頻數的多少,矩形的高度表示每一組的頻數或頻率,寬度則表示各組的組距,因此其高度與寬度均有意義。
- 由於分組數據具有連續性,柱狀圖的各矩形通常是連續排列,而條形圖則是分開排列。
- 柱狀圖主要用於展示分類數據,而直方圖則主要用於展示數據型數據
格式:pyplot.hist(x, bins=None, range=None, normed=False, weights=None, cumulative=False, bottom=None, histtype=’bar’, align=’mid’, orientation=’vertical’, rwidth=None, log=False, color=None, label=None, stacked=False, hold=None, data=None, **kwargs)
- x:指定每個bin(箱子)分布的數據,對應x軸
- bins : 這個參數指定bin(箱子)的個數,也就是總共有幾條條狀圖
- normed : 是否將得到的直方圖向量歸一化
- histtype : {‘bar’, ‘barstacked’, ‘step’, ‘stepfilled’}
函數返回值:
- n : array or list of arrays(箱子的值)
- bins : array(箱子的邊界)
- patches : list or list of lists
stackplot:面積圖
格式:stackplot(x, *args, labels=(), colors=None, baseline='zero', data=None, **kwargs)
示例 :
1 plt.stackplot(year, gdp, y_data, colors=['r', 'g']) 2 plt.title("stackplot 面積圖") 3 plt.show()
效果:
從圖上看不出顏色代表的含義,增加圖例,完整代碼如下:

1 def draw_stackplot(): 2 plt.plot([], [], color='r', label='gdp', linewidth=5) 3 plt.plot([], [], color='g', label='y_data', linewidth=5) 4 plt.stackplot(year, gdp, y_data, colors=['r', 'g']) 5 plt.title("stackplot 面積圖") 6 plt.legend() 7 plt.show()
效果圖:
subplot:子圖布局
subplot 在一張數據圖上包含多個子圖,格式:subplot(nrows, ncols, index, **kwargs)
- nrows:指定將數據圖區域分成多少行;
- ncols:指定將數據圖區域分成多少列;
- index:指定獲取第幾個區域
subplot() 函數也支持直接傳入一個三位數的參數,其中第一位數將作為 nrows 參數;第二位數將作為 ncols 參數;第三位數將作為 index 參數。
示例:

1 def draw_subplot(): 2 plt.figure(figsize=(4, 3)) 3
4 x_data = np.linspace(-np.pi, np.pi, 64, endpoint=True) 5 plt.subplot(2, 1, 1) 6 plt.plot(x_data, np.sin(x_data)) 7 plt.gca().spines['top'].set_color('none') 8 plt.gca().spines['right'].set_color('none') 9 plt.gca().spines['left'].set_position(('data', 0)) 10 plt.gca().spines['bottom'].set_position(('data', 0)) 11 plt.title('sin') 12
13 plt.subplot(2, 2, 3) 14 plt.plot(x_data, np.cos(x_data)) 15 plt.gca().spines['top'].set_color('none') 16 plt.gca().spines['right'].set_color('none') 17 plt.gca().spines['left'].set_position(('data', 0)) 18 plt.gca().spines['bottom'].set_position(('data', 0)) 19 plt.title('cos') 20
21 plt.subplot(2, 2, 4) 22 plt.plot(x_data, np.tan(x_data)) 23 plt.gca().spines['top'].set_color('none') 24 plt.gca().spines['right'].set_color('none') 25 plt.gca().spines['left'].set_position(('data', 0)) 26 plt.gca().spines['bottom'].set_position(('data', 0)) 27 plt.title('tan') 28
29 plt.show()
效果:
GridSpec:網格布局
指定在給定GridSpec中的子圖位置
示例:

1 def draw_gridspace(): 2 plt.figure(figsize=(4, 3)) 3
4 x_data = np.linspace(-np.pi, np.pi, 64, endpoint=True) 5 gs = gridspace.GridSpec(2, 2) 6 ax1 = plt.subplot(gs[0, :]) 7 ax2 = plt.subplot(gs[1, 0]) 8 ax3 = plt.subplot(gs[1, 1]) 9
10 ax1.plot(x_data, np.sin(x_data)) 11 ax1.spines['top'].set_color('none') 12 ax1.spines['right'].set_color('none') 13 ax1.spines['left'].set_position(('data', 0)) 14 ax1.spines['bottom'].set_position(('data', 0)) 15 ax1.set_title('sin') 16
17 ax2.plot(x_data, np.cos(x_data)) 18 ax2.spines['top'].set_color('none') 19 ax2.spines['right'].set_color('none') 20 ax2.spines['left'].set_position(('data', 0)) 21 ax2.spines['bottom'].set_position(('data', 0)) 22 ax2.set_title('cos') 23
24 ax3.plot(x_data, np.tan(x_data)) 25 ax3.spines['top'].set_color('none') 26 ax3.spines['right'].set_color('none') 27 ax3.spines['left'].set_position(('data', 0)) 28 ax3.spines['bottom'].set_position(('data', 0)) 29 ax3.set_title('tan') 30
31 plt.show()
效果與上節 subplot 一致
參考資料
- https://blog.csdn.net/u014539580/article/details/78207537
- https://blog.csdn.net/u010758410/article/details/71743225
- https://cloud.tencent.com/developer/news/320526
- figure:https://blog.csdn.net/m0_37362454/article/details/81511427
- spines:https://blog.csdn.net/qq_41011336/article/details/83015986
- bar1: https://blog.csdn.net/jiede1/article/details/61208576
- bar2: https://blog.csdn.net/liangzuojiayi/article/details/78187704
- bar3:http://c.biancheng.net/view/2716.html
- pie:http://c.biancheng.net/view/2713.html
- scatter: http://c.biancheng.net/view/2718.html
- hist:https://blog.csdn.net/lmj_2529980619/article/details/86063752
- hist:https://www.cnblogs.com/python-life/articles/6084059.html
- Stackplot:http://blog.sina.com.cn/s/blog_683754910102whwq.html
- subplot:http://c.biancheng.net/view/2711.html