准備工作
我們需要先安裝matplotlib庫,然后導入庫,這些很簡單,我就不講了,哦,把numpy也導入進來。
import matplotlib.pyplot as plt import numpy as np
正式開始
plt.和ax.
我們經常會在畫圖的代碼里看到,有用plt.的,有用ax.的,兩者到底有什么區別呢,畫的圖有什么不一樣嗎,我們先來用兩種經常看到的方式實現一下。
plt.
fig=plt.figure(num=1,figsize=(4,4))
plt.plot([1,2,3,4],[1,2,3,4])
plt.show()
ax.
fig=plt.figure(num=1,figsize=(4,4))
ax=fig.add_subplot(111)
ax.plot([1,2,3,4],[1,2,3,4])
plt.show()
我們看到上面兩種畫圖方式可視化結果並無不同,那區別在哪呢?
其實呢,第一種方式呢,是先生成了一個畫布,然后在這個畫布上隱式的生成一個畫圖區域來進行畫圖,第二種方式,先生成一個畫布,然后,我們在此畫布上,選定一個子區域畫了一個子圖,上一張官方的圖,看看你能不能更好的理解
除了ax之外,我們也可以直接用plt添加子圖,方式如下
fig=plt.figure(num=1,figsize=(4,4))
plt.subplot(111)
plt.plot([1,2,3,4],[1,2,3,4])
plt.show()
你看,這樣添加子圖,也是一樣的,fig,生成一個畫布,plt.subplot(111),將畫布分為1x1的分布,並選中第一個子圖進行操作。雖然這樣看着一樣呢,但是后面修飾圖片的時候,ax這個方式比plt的方式更加方便。因此,本文我們用ax方式來學習畫圖,也希望大家都提前選定一種自己喜歡的方式來畫圖,添加子圖,等一些列操作。
子圖的創建
在上一節的介紹中,講到了子圖,可能剛接觸畫圖的同學,會有點疑惑,這節,我們來詳細講講子圖。我們可以這樣來考慮問題,我們畫圖的時候,找到一張紙(畫布),然后打算把這張紙分成幾個區域(子圖)來畫幾幅不同的畫。子圖的創建可以是一些簡單創建,比如這樣的
fig=plt.figure(num=1,figsize=(4,4))
ax1=fig.add_subplot(221)###可從圖中看到,我們的畫布是分為2x2的區域
ax1.plot([1,2,3,4],[1,2,3,4])
ax2=fig.add_subplot(222)
ax2.plot([1,2,3,4],[2,2,3,4])
ax3=fig.add_subplot(223)
ax3.plot([1,2,3,4],[1,2,2,4])
ax4=fig.add_subplot(224)
ax4.plot([1,2,3,4],[1,2,3,3])
plt.show()
簡單子圖創建
ax1=fig.add_subplot(221),221里面前兩個代表的是畫布划分的行數和列數,公共分為4個子圖,最后一個1是代表,現在選中第一個子圖。
import matplotlib.gridspec as gridspec#調用網格
fig=plt.figure(num=1,figsize=(4,6))#創建畫布
gs=gridspec.GridSpec(3,3)#設定網格
ax1=fig.add_subplot(gs[0,:])#選定網格
ax1.plot([1,2,3,4],[1,2,3,4])
ax2=fig.add_subplot(gs[1,:-1])
ax2.plot([1,2,3,4],[1,2,3,4])
ax3=fig.add_subplot(gs[1:,-1])
ax3.plot([1,2,3,4],[1,2,3,4])
ax4=fig.add_subplot(gs[2,0])
ax4.plot([1,2,3,4],[1,2,3,4])
ax5=fig.add_subplot(gs[2,1])
ax5.plot([1,2,3,4],[1,2,3,4])
plt.show()
復雜子圖構建
常用通用函數講解
現在跳過剛剛哪些比較大的方向,講解一些比較細碎且通用又常用的畫圖函數,這些函數可以說是裝飾我們的圖,使得我們的圖更加美觀且直觀的裝飾品。
我們舉個例子來講解,使大家更直觀地看到我們講解的函數在圖的繪制中的作用。
例1:現有某某水果店一周的蘋果的銷售記錄數,店長想更加直觀的觀察比較這一周的銷售情況。銷售情況:apple=[78kg,80kg,79kg,81kg,91kg,95kg,96kg]
app=[78,80,79,81,91,95,96]
x=np.arange(1,8)
fig=plt.figure(num=1,figsize=(6,4))
ax=fig.add_subplot(111)
ax.plot(x,app)
plt.show()
1
看着這個圖,什么感受,我是覺得難看!
注:這里我們直接用了plot()函數畫了一個坐標圖,這是一個封裝好的函數,我們輸入參數,就可直接生成此樣式的圖,除此之外還有餅圖,散點圖,直方圖,我們下一篇講這些已經封裝好的圖。
現在我想給它裝修一下,比如在x軸上加入星期類標,還想這個圖里的折線能不能懸浮在上空,給圖加個標題等等。在開始裝修之前,我們先來個小插曲,就是在圖中顯示中文的問題,如果我們不搞點操作,你會發現,你的中文在圖中會以一個個正方形框框顯示。
插曲:中文顯示問題
plt.rcParams["font.family"]="SimHei"
加入一行這個代碼,我們的中文就能正確顯示了,這行代碼就是把我們的字體設置為“SimHei”中文黑體。除了字體設置還有以下屬性
字體的樣式有以下選擇
除了在全局設置字體外,我們也可以在特征顯示中文的位置設置一個屬性fontproperties,這個,我們講到再給大家演示。
現在回來,我們繼續講裝修圖的問題,介紹幾個函數
#函數里的參數,是根據我們的例子特定設置的,不同問題,不同的設置,
需要看圖片效果,找參數
#設置刻度范圍
ax.set_xlim(1,7.1)#x軸從1到7.1
ax.set_ylim(40,100)#y軸從40到100
#設置顯示的刻度
ax.set_xticks(np.linspace(1,7,7))#np.linspace()函數為等差數列,1至7的7個數組成的等差數列1,2,3,4,5,6,7,
ax.set_yticks(np.linspace(50,100,6))#關於等差數列,想了解的可以參看numpy的用法
#設置刻度標簽
ax.set_xticklabels(["星期一","星期二","星期三","星期四","星期五","星期六","星期日"],fontproperties="SimHei"\
,fontsize=12)
#這里用到了屬性fontproperties可以單獨設置x軸標簽的字體,也可以用fontsize設置字體大小,還可以用color
設置字的顏色
ax.set_yticklebels(["50kg","60kg","70kg","80kg","90kg","100kg"],fontsize=12)
現在我們來加進我們之前畫圖的代碼中,看看效果
app=[78,80,79,81,91,95,96]
x=np.arange(1,8)
fig=plt.figure(num=1,figsize=(6,4))
ax=fig.add_subplot(111)
ax.plot(x,app)
ax.set_xlim([1,7.1])
ax.set_ylim([40,100])
ax.set_xticks(np.linspace(1,7,7))
ax.set_yticks(np.linspace(50,100,6))#可調控字體大小,樣式,
ax.set_xticklabels(["星期一","星期二","星期三","星期四","星期五","星期六","星期日"],fontproperties="SimHei",\
fontsize=12,rotation=10)
#參數rotation=10,可以使得類標旋轉值為10的角度
ax.set_yticklabels(["50kg","60kg","70kg","80kg","90kg","100kg"])
plt.show()
2
這是初步修改過的圖,我們現在裝飾一下軸上的刻度線,使得y軸中不顯示刻度線和其他的一些小細節修改。
tick_params()函數
##借用函數tick_params()可以裝修軸上的刻度線和軸標簽
ax.tick_params()
###看一下此函數的一些重要參數
- axis: 可選"x","y","both",默認"both",分別代表,對x軸操作,對y軸操作,對兩個軸都操作。
- direction: 可選 "in","out","inout"代表,刻度線顯示在坐標軸里面,坐標軸外邊,雙邊
為了更加顯眼,讓大家看出不同,我超綱操作了一下,給刻度線設置一下顏色,和長度,可以看出區別了吧,現在我們就把超綱的地方補上。
- length: 刻度線長度,上面圖里的刻度線長度,我設置的為6
- color: 刻度線顏色,上面圖里的刻度線顏色,我設置的為“r”
- width: 刻度線寬度
- pad: 刻度線與刻度標簽之間的間隔
- bottom, top, left, right四個參數對應四個邊框,它們的取值為布爾類型,True 表示顯示對應邊框上的刻度線,False,代表不顯示,默認True
- labelbottom, labeltop, labelleft, labelright,與上面四個對應,代表的是四個邊框上的類標的設置,取值為布爾類型,True代表顯示對應邊框上的類標,False代表不顯示。
- labelsize:類標大小的設置參數,可取浮點型數值,也可去"medium","large","small"
- labelrotation:旋轉類標一定的角度,與在set_xticklabels()中的參數rotation作用相同。
我們來實際操作一下
#將此代碼插入到之前的代碼中即可
ax.tick_params(left=False,pad=8,direction="in",length=2,width=3,color="b",labelsize=12)
ax.tick_params("x",labelrotation=10)#類標旋轉
3
y軸上的刻度線沒有了。
添加軸坐標標簽,表頭,圖例
ax.set_xlabel("星期")#添加x軸坐標標簽,后面看來沒必要會刪除它,這里只是為了演示一下。
ax.set_ylabel("銷售量",fontsize=16)#添加y軸標簽,設置字體大小為16,這里也可以設字體樣式與顏色
ax.set_title("某某水果店一周水果銷售量統計圖",fontsize=18,backgroundcolor='#3c7f99'\
fontweight='bold',color='white',verticalalignment="baseline")#標題(表頭)
4
使用到的set_title()參數有很多,介紹幾個常用的
- fontsize:默認12,可選參數還有['xx-small', 'x-small', 'small', 'medium', 'large','x-large', 'xx-large']
- backgroundcolor:背景顏色
- fontweight:字體粗細,可選參數為['light', 'normal', 'medium', 'semibold', 'bold', 'heavy', 'black']
- color:字體顏色
- fontstyle:設置字體類型,可選參數[ 'normal' | 'italic' | 'oblique' ],italic斜體,oblique傾斜
- verticalalignment:設置水平對齊方式 ,可選參數 : 'center' , 'top' , 'bottom' ,'baseline'
此參數可設置title與正圖的位置 。
目前得到的圖中,我想把上,右軸的線給去掉,給其他兩個軸線換一下粗細合顏色,怎么做?
aplines
#ax.spines["left"].set_color("darkblue")#設置左軸的顏色,我們圖中未用
#ax.spines["bottom"].set_linewidth(3)#底軸線條寬度設置
ax.spines["top"].set_visible(False)#上軸不顯示
ax.spines["right"].set_visible(False)#右
ax.spines["left"].set_visible(False)#左
添加到之前的代碼中
5
圖例添加legend()
ax.legend(("蘋果"),loc=3,labelspacing=2,handlelength=4,fontsize=14,shadow=True)
##一般添加圖例時,會在畫圖的函數里,比如ax.plot()函數中添加一個label參數,則后面直接ax.legend(loc="")
##不需要第一個參數了。
###loc的可取"best",1或者"upper right",2或"upper left",3或"lower left",4或"lower right",代表放不同位置
- loc:可取"best",1或者"upper right",2或"upper left",3或"lower left",4或"lower right",代表放不同位置
- fontsize: int或float或{‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’},字體大小
- shadow: 是否為圖例邊框添加陰影
- labelspacing: 圖例中條目之間的距離
- handlelength: 圖例句柄的長度
ax.plot(x,app,label="蘋果")
ax.legend(loc=3,labelspacing=2,handlelength=3,fontsize=14,shadow=True)
6
有沒有覺得我們的圖像點樣子了,哈哈,還是有點不好看,覺得圖中的折線不好看,怎么調呢,為了造好看的圖,我們先來學習ax.plot()函數
ax.plot(x,y,format_string) 坐標圖
- x: x軸數據,列表或數組,可選參數,當我們在這個函數里,只展示一組數據時,x可省略。
- y: y軸數據,必須有。
- format_string:主要來控制我們畫的曲線的格式:顏色,風格,標記,可取三者的組合如:“g-o”,"r-.D",如果不用組合,則用color,marker,linestyle,三個參數分別指定。
- label: 添加圖例的類標。
顏色
風格
標記
#ax.plot(x,app,label="蘋果")
ax.plot(x,app,"r-.d",label="蘋果")#在原來的基礎上添加“r-.d”
7
如果店長有搞了這周香蕉的銷售量,想與蘋果的銷售量做一下對比
##添加此行代碼
ban=[70,80,81,82,75,90,89]
ax.plot(x,ban,"c-d",label="香蕉")
8
這樣看着還挺不錯,不知道我審美有沒有問題,嘻嘻!
還有一個比較常用的函數,ax.text(),可以在圖中指定位置添加標簽
ax.text(),參數講解
- x,y: 放置text的位置,橫縱坐標。
- s: str,text內容。
- fontsize: 設置字體大小,默認12,可選參數 [‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’,‘x-large’, ‘xx-large’]
- fontweight:設置字體粗細,可選參數 [‘light’, ‘normal’, ‘medium’, ‘semibold’, ‘bold’, ‘heavy’, ‘black’]
- alpha: 透明度,參數值0至1之間。
- rotation: (旋轉角度)可選參數為:vertical,horizontal 也可以為數字。
- backgroundcolor:背景顏色。
- color: 字體顏色。
##最后添加此操作,得到的圖
ax.text(7,97,"max:96",fontsize=14,color="g",alpha=1)
ax.text(6,86,"max:90",fontsize=12,alpha=1)
9
除了text()函數可以添加標注之外,還有一個可以添加箭頭的標注函數annotate()
annotate():參數講解
- s: 添加標注的內容,字符串形式。
- xy: 箭頭指向的位置,就是我們想添加標注的對象,元組類型輸入方式。
- xytext:添加標注的實際位置,標注實際所在位置,可看做箭頭輸出端。
- arrowprops: 此參數中提供箭頭屬性字典來繪制從文本到注釋點的箭頭。
width : 箭把寬度,整數或浮點數。
frac:箭頭頭部所占的比例,小於1。
headwidth:箭頭頭部寬度,整數或浮點數。
headlength: 箭頭長度,整數或浮點數。
facecolor: 填充色 。
shrink:移動提示,並使其離注釋點和文本一些距離,<1,大白話說就是,別讓箭頭兩端
里標注點和文本太近。
- frontsize:可以設置字大小,這個參數遇到很多次了。
我們來設置一下
ax.annotate(s="min:70",xy=(1,70),xytext=(1.3,66),arrowprops=dict(facecolor="y",shrink=0.05,\ headwidth=12,headlength=6,width=4\ ),fontsize=12)
最后
我把最全代碼放一下
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["font.family"]="SimHei"
app=[78,80,79,81,91,95,96]
ban=[70,80,81,82,75,90,89]
x=np.arange(1,8)
fig=plt.figure(num=1,figsize=(6,4))
ax=fig.add_subplot(111)
ax.plot(x,app,"r-.d",label="蘋果")
ax.plot(x,ban,"c-d",label="香蕉")
ax.set_xlim([1,7.1])
ax.set_ylim([40,100])
ax.set_xticks(np.linspace(1,7,7))
ax.set_yticks(np.linspace(50,100,6))#可調控字體大小,樣式,
ax.set_xticklabels(["星期一","星期二","星期三","星期四","星期五","星期六","星期日"],fontproperties="SimHei",fontsize=12)
ax.set_yticklabels(["50kg","60kg","70kg","80kg","90kg","100kg"])
ax.tick_params(left=False,pad=8,direction="in",length=2,width=3,color="b",labelsize=12)
ax.tick_params("x",labelrotation=10)#類標旋轉
#ax.set_xlabel("星期")#添加x軸坐標標簽,后面看來沒必要會刪除它,這里只是為了演示一下。
ax.set_ylabel("銷售量",fontsize=16)#添加y軸標簽,設置字體大小為16,這里也可以設字體樣式與顏色
ax.set_title("某某水果店一周水果銷售量統計圖",fontsize=18,backgroundcolor='#3c7f90',\
fontweight='bold',color='white',verticalalignment="baseline")
#ax.spines["left"].set_color("darkblue")#設置左軸的顏色
#ax.spines["bottom"].set_linewidth(2)#底軸線條寬度設置
ax.spines["top"].set_visible(False)#上軸不顯示
ax.spines["right"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.text(7,97,"max:96",fontsize=14,color="g",alpha=1)
ax.text(6,86,"max:90",fontsize=12,alpha=1)
ax.annotate(s="min:70",xy=(1,70),xytext=(1.3,66),arrowprops=dict(facecolor="y",shrink=0.05,\
headwidth=12,headlength=6,width=4\
),fontsize=12)
ax.legend(loc=3,labelspacing=1,handlelength=3,fontsize=14,shadow=True)
plt.show()
還有一個關於,圖中顏色的問題,顏色的種類選擇,大家網上一搜都有,這里只要帶顏色的參數,都可用。
最后講解一個圖片保存成.jpg和.png文件的函數:plt.savefig("保存的文件路徑")
注:此函數需放置在show()函數之前。
#保存為jpg文件
plt.savefig("figure.jpg")#我這里填的是相對路徑,如果想保存在指定文件夾下,填寫絕對路徑。
#保存為png文件
plt.savefig("figure.png")
plt.savefig()有一個參數為bbox_inches,將此參數設置為bbox_inches="tight"時,說是可刪除圖片邊緣空格,我實驗了一下,確實會使保存的圖片有些許變化。可實驗操作一下。
還有一點需要注意,如果未設置圖片的大小,則保存的圖片與show()的圖片會有差異。因此如果想將保存的圖片與show()出來的圖片大小一樣,需要提前設置圖片大小。
#此函數里的參數figsize可設置圖片大小
fig=plt.figure(num=1,figsize=(6,4))
#!/usr/bin/env python # !_*_ coding:utf-8 _*_ import matplotlib.pyplot as plt import numpy as np import matplotlib.gridspec as gridspec plt.rcParams['font.family'] = 'SimHei' x = np.arange(1, 8) app = [78, 80, 79, 81, 91, 95, 96] fig = plt.figure(num=1, figsize=(8, 6)) ax = fig.add_subplot(111) # 設置刻度范圍 ax.set_xlim(1, 7.1) ax.set_ylim(40, 100) # plt.xlim(1, 7.1) # plt.ylim(40, 100) # 設置顯示的刻度 # ax.set_xticks(np.linspace(1, 7, 7)) # ax.set_yticks(np.linspace(50, 100, 6)) # plt.xticks(np.linspace(1, 7, 7)) # plt.yticks(np.linspace(50, 100, 11)) # 設置刻度標簽 # ax.set_xticklabels(['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日', ], color='green', rotation=20) # ax.set_yticklabels(['50kg', '60kg', '70kg', '80kg', '90kg', '100kg'], fontsize=12) plt.xticks(np.linspace(1, 7, 7), labels=['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'], color='green', rotation=20) plt.yticks(np.linspace(50, 100, 6), labels=['50kg', '60kg', '70kg', '80kg', '90kg', '100kg'], fontsize=12) # ax.tick_params(left=False, pad=5, direction='in', length=10, width=3, color='r') plt.tick_params(direction='inout') # 添加軸坐標標簽,表頭,圖例 ax.set_xlabel("星期", fontsize=18) ax.set_ylabel("銷售量", fontsize=18) ax.set_title("某某水果店一周水果銷售統計量", fontsize=18, backgroundcolor='blue', fontweight='bold', color='red', verticalalignment="baseline") # 對坐標軸的操作 ax.spines['left'].set_color('darkblue') ax.spines['left'].set_linewidth(5) # 添加圖例 # ax.plot(x,y,format_string) 坐標圖 # 用color,marker,linestyle,三個參數分別指定。----- format_string plt.plot(x, app, "r-.d") ban = [70, 80, 81, 82, 75, 90, 89] ax.plot(x, ban, "c-d", label='香蕉') ax.legend(("蘋果", "香蕉"), loc=0, labelspacing=2, handlelength=1, fontsize=12, shadow=True) # ax.text()參數 ax.text(7, 97, s="max:96", fontsize=14, color='g', alpha=1) plt.text(6, 86, "max:90", fontsize=12, alpha=0.3) # 除了text()函數可以添加標注之外,還有一個可以添加箭頭的標注函數annotate() plt.annotate(text="min:70", xy=(1, 70), xytext=(1.33, 66), arrowprops=dict(facecolor="y", shrink=0.05, headwidth=12, headlength=6, width=4)) plt.show()