用Python繪制圖表在工作中是一項非常有用的技能,雖然說強(qiáng)大的matlab基本可以滿足我們所有的繪圖需求,但是在有些情況下,使用Python繪圖,讓圖表直接可以直接隨著Python程序的運行而產(chǎn)生。那這種便捷,也是非常有價值的。本文中,我將簡單介紹使用Python的pyplot模塊繪制圖表的基本操作。當(dāng)然繪圖是一個細(xì)活,不同的實際需求,對圖表的要求也是千變?nèi)f化,所以,要把所有的繪圖操作一一道來,是困難的,也不見得有多大價值。因此,本文更多的只是拋磚引玉罷了,更詳細(xì)的繪圖技巧大家應(yīng)在實踐中不斷查閱,積累經(jīng)驗。
matplotlib是python最著名的繪圖庫,它提供了一整套和matlab相似的命令A(yù)PI,十分適合交互式地行制圖。其中,matplotlib的pyplot模塊一般是最常用的,可以方便用戶快速繪制二維圖表。
折線圖在我的工作中用到的比較多,因為寫論文時,經(jīng)常要在不同的參數(shù)環(huán)境下比較算法的運行時間。同時,折線圖也是最簡單的,所以我拿它“開刀”,來介紹pyplot模塊最基本的操作。
現(xiàn)在繪制一個簡單的二維折線圖,x值和對應(yīng)的y值分別可以被表示如下:,我們可以按如下代碼畫出折線圖。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4]
y = [1.2, 2.5, 4.5, 7.3]
# plot函數(shù)作圖
plt.plot(x, y)
# show函數(shù)展示出這個圖,如果沒有這行代碼,則程序完成繪圖,但看不到
plt.show()
需要注意一下的是show()
函數(shù)在通常的運行情況下,將會阻塞程序的運行,直到用戶關(guān)閉繪圖窗口。換句話說,在關(guān)閉show()
函數(shù)彈出的圖像窗口前,show()
函數(shù)后面的代碼不會運行,直到用戶關(guān)閉圖像窗口,才會繼續(xù)。
此外,還可以調(diào)用plt.savefig()
將當(dāng)前的Figure對象保存成圖像文件,圖像格式由圖像文件的擴(kuò)展名決定。比如,我通過如下代碼將生成的圖像保存為”test.png”。并且用dpi參數(shù)指定圖像的分辨率為120。最后,輸出圖像的寬度為個像素。
plt.savefig("test.png", dpi=120)
注意:plt.savefig()
函數(shù)應(yīng)該出現(xiàn)在plt.show()
函數(shù)之前,否則,關(guān)閉圖像窗口后,圖像對象也就被釋放了,什么都保存不到。
當(dāng)然了,這個圖十分簡陋,簡陋到幾乎不能用,現(xiàn)在我們一步步去優(yōu)化這個圖。
首先,可以對折線本身的風(fēng)格進(jìn)行優(yōu)化。最好是每個記錄的點突出,同時折線的顏色,粗細(xì)以及樣式可控。優(yōu)化后,我們得到了下圖:
具體的實現(xiàn)代碼如下:
import matplotlib.pyplot as plt
x = [1, 2, 3, 4]
y = [1.2, 2.5, 4.5, 7.3]
plt.plot(x, y, color="r", linestyle="--", marker="*", linewidth=1.0)
plt.show()
解釋一下,plot函數(shù)中,后面的參數(shù)分別用來控制線條顏色,線條風(fēng)格,線條標(biāo)記以及線條粗細(xì)。這個編碼風(fēng)格和matlab是極為相似的。我將常用的參照表摘抄如下,供參考:
線條風(fēng)格
線條風(fēng)格 | 實線 | 虛線 | 破折線 | 點畫線 | 無線條 |
---|---|---|---|---|---|
代碼表示 | - | : | – | -. | None 或 , |
線條顏色
線條顏色 | 紅 | 洋紅 | 黃 | 綠 | 青 | 藍(lán) | 黑 | 白 |
---|---|---|---|---|---|---|---|---|
代碼表示 | r | m | y | g | c | b | k | w |
線條標(biāo)記
標(biāo)記 | 描述 | 標(biāo)記 | 描述 | 標(biāo)記 | 描述 |
---|---|---|---|---|---|
o | 圓圈 | . | 點 | * | 星號 |
+ | 加號 | v | 朝下三角 | ^ | 朝上三角 |
< | 朝左三角 | > | 朝右三角 | D | 大菱形 |
d | 小菱形 | s | 正方形 | p | 五邊形 |
H | 大六邊形 | h | 小六邊形 | p | 八邊形 |
x | ?號 | None或, | 無標(biāo)記 |
線條是我們想要的樣子了,再來優(yōu)化坐標(biāo)軸。這當(dāng)中主要涉及的是坐標(biāo)軸的范圍,取值以及名稱。我們現(xiàn)在重新繪制一個連續(xù)的曲線。以之間的函數(shù)圖,代碼以及對應(yīng)圖像如下:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-5, 5, 0.02)
y = np.sin(x)
plt.axis([-np.pi, np.pi, -2, 2])
plt.plot(x, y, color="r", linestyle="-", linewidth=1)
plt.show()
可以看出對控制的是y軸方向的取值。
總結(jié)一下,下面形式的函數(shù)可以控制圖像的繪圖范圍:
plt.axis([x_min, x_max, y_min, y_max])
如果只是單獨想要控制x軸或者y軸的取值,則可以用plt.xlim(x_min, x_max)
和plt.ylim(y_min, y_max)
,用法與plt.axis()
類似。
函數(shù)plt.xlabel()
和plt.xlabel()
用來實現(xiàn)對x軸和y軸添加標(biāo)題
函數(shù)plt.xticks()
和plt.xticks()
用來實現(xiàn)對x軸和y軸坐標(biāo)間隔(也就是軸記號)的設(shè)定。用法上,函數(shù)的輸入是兩個列表,第一個表示取值,第二個表示標(biāo)記。當(dāng)然如果你的標(biāo)記就是取值本身,則第二個列表可以忽略。下面我舉一個例子:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-2 * math.pi, 2 * math.pi, 0.02)
y = np.sin(x)
plt.axis([-10, 10, -2, 2])
plt.xticks([i * np.pi/2 for i in range(-4, 5)], [str(i * 0.5) + "$\pi$" for i in range(-4, 5)])
plt.yticks([i * 0.5 for i in range(-4, 5)])
plt.xlabel("x")
plt.ylabel("y")
plt.plot(x, y, color="r", linestyle="-", linewidth=1)
plt.show()
畫出的圖像如下所示:
可以看到plt.xticks()
中,后面的列表存儲了應(yīng)該出現(xiàn)的所有標(biāo)記,這是我們自定義的標(biāo)記,而且,這里是支持latex公式表達(dá)的。
大多時候,需要在同一張圖中出現(xiàn)多條曲線,以便我們對數(shù)據(jù)有個直觀的比較。那么做法非常簡單,直接寫多個作圖函數(shù)plot()
即可,比如,我按照如下代碼,將兩條曲線畫在同一張圖中。
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-1, 1, 0.1)
y1 = np.exp(x)
y2 = np.exp(2 * x)
plt.plot(x, y1, color="r", linestyle="-", marker="^", linewidth=1)
plt.plot(x, y2, color="b", linestyle="-", marker="s", linewidth=1)
plt.xlabel("x")
plt.ylabel("y")
plt.show()
figure()
函數(shù)可以幫助我們同時處理生成多個圖,而subplot()
函數(shù)則用來實現(xiàn),在一個大圖中,出現(xiàn)多個小的子圖。需要注意的是,figure()
中的參數(shù)為圖片序號,一般是按序增加的,這里面還涉及一個當(dāng)前圖的概念,具體可以通過下面的例子來理解;subplot()
中的參數(shù)一般有3個,分別為行數(shù),列數(shù),以及子圖序號。比如,subplot(1, 2, 1)
表示這是一個1行,2列布局的圖(兩個子圖,在同一行,分居左右),其中,當(dāng)前處理的子圖是第一個圖(也就是左圖)。我舉個例子:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-1, 1, 0.1)
y1 = np.exp(x)
y2 = np.exp(2 * x)
y3 = np.exp(1.5 * x)
plt.figure(1) # 生成第一個圖,且當(dāng)前要處理的圖為fig.1
plt.subplot(1, 2, 1) # fig.1是一個一行兩列布局的圖,且現(xiàn)在畫的是左圖
plt.plot(x, y1, color="r", linestyle="-", marker="^", linewidth=1) # 畫圖
plt.xlabel("x")
plt.ylabel("y1")
plt.figure(2) # 生成第二個圖,且當(dāng)前要處理的圖為fig.2
plt.plot(x, y2, color="k", linestyle="-", marker="s", linewidth=1) # 畫圖,fig.2是一張整圖,沒有子圖,默認(rèn)subplot(1, 1, 1)
plt.xlabel("x")
plt.ylabel("y2")
plt.figure(1) # 當(dāng)前要處理的圖為fig.1,而且當(dāng)前圖是fig.1的左圖
plt.subplot(1, 2, 2) # 當(dāng)前圖變?yōu)閒ig.1的右圖
plt.plot(x, y3, color="b", linestyle="-", marker="v", linewidth=1)
plt.xlabel("x")
plt.ylabel("y3")
plt.show()
這樣,我們就用一個腳本畫了兩張圖fig.1和fig.2。其中,fig.1包含了分居左右的兩個子圖,分別是y1和y3的曲線;fig.2是一張整圖,畫的是y2曲線。我將fig.1展示如下:
如果希望某個子圖占據(jù)整行或者整列,可以如下調(diào)用subplot():
plt.subplot(221) # 第一行的左圖
plt.subplot(222) # 第一行的右圖
plt.subplot(212) # 第二整行
plt.show()
畫底下的大圖時,實際上相當(dāng)于把前兩個小的子圖看作一個整圖。
函數(shù)plt.title()
用來對圖像命名。
函數(shù)plt.legend()
用來為圖像添加圖例。標(biāo)題和圖例我用以下的例子做一個簡單介紹:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-1, 1, 0.1)
y1 = np.exp(x)
y2 = np.exp(2 * x)
plt.plot(x, y1, color="r", linestyle="-", marker="^", linewidth=1, label="y1")
plt.plot(x, y2, color="b", linestyle="-", marker="s", linewidth=1, label="y2")
plt.legend(loc='upper left', bbox_to_anchor=(0.2, 0.95))
plt.title("Figure 1")
plt.show()
legend()
里面的參數(shù)loc
表示圖例的位置,參數(shù)bbox_to_anchor
是一個二元組,用來進(jìn)一步細(xì)化圖例的位置,其中第一個數(shù)值用于控制legend的左右移動,值越大越向右邊移動,第二個數(shù)值用于控制legend的上下移動,值越大,越向上移動。此外,我們在畫兩條曲線時,分別為它們添加了標(biāo)簽label
,標(biāo)簽的內(nèi)容也就是最后圖例中對應(yīng)的內(nèi)容。
和matlab一樣,用函數(shù)grid()
添加網(wǎng)格,函數(shù)中我們可以定義網(wǎng)格的樣式,比如線條顏色,類型,粗細(xì)等等。需要注意的是,如果你只想在對x軸,或者y軸添加網(wǎng)格,只需要設(shè)定參數(shù)axis="x"
或axis="y"
即可。axis參數(shù)一般默認(rèn)為"both"
表示,兩個維度上都建立網(wǎng)格。
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-1, 1, 0.1)
y = [2 * i for i in x]
plt.plot(x, y, color="r", linestyle="-", marker="^", linewidth=1)
plt.grid(color="k", linestyle=":")
plt.show()
通過向plt.subplot()
函數(shù)傳遞參數(shù)facecolor
設(shè)置圖像的背景色。需要注意的是背景色的設(shè)置代碼應(yīng)該在繪制曲線之前,否則相當(dāng)于給整張圖上色,覆蓋了要展示的曲線。比如下圖,我設(shè)置背景色為綠色。其實這個功能在我看來實在是沒什么大用,大多情況下,我們要用到的背景色都是白色,也就是默認(rèn)的背景色。
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-1, 1, 0.1)
y1 = np.exp(x)
y2 = np.exp(2 * x)
plt.subplot(facecolor="g")
plt.plot(x, y1, color="r", linestyle="-", marker="^")
plt.plot(x, y2, color="b", linestyle="-", marker="s")
plt.grid(color="k", linestyle=":")
plt.show()
plt.text()
, plt.annotate()
是兩種向圖像添加文本注釋的方法。plt.text()
可以在圖像任意位置添加文字,plt.annotate()
則可以幫助我們形象地為曲線中的某一個點添加注釋。
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-1, 1, 0.1)
y1 = np.exp(x)
y2 = np.exp(2 * x)
plt.plot(x, y1, color="r", linestyle="-", marker="^", linewidth=1)
plt.plot(x, y2, color="b", linestyle="-", marker="s", linewidth=1)
plt.text(-0.5, 3, "exp functions", fontsize=10)
plt.show()
plt.text()
中前兩個參數(shù)表示添加文字的坐標(biāo)位置,最后一個參數(shù)是要添加的文本。
plt.annotate()
與plt.text()
類似,代碼表示如下:
plt.annotate('A', xy=(0, 1), xytext=(-0.5, 2.5), arrowprops=dict(facecolor='k', headwidth=10, width=2))
分別解釋一下,第一個參數(shù)’A’是注釋文本,xy
表示要注釋的點的坐標(biāo),xytext
表示注釋文本的起始坐標(biāo),arrowprops
表示箭頭,我們可以通過一個字典形的變量,設(shè)置其樣式,包括顏色,寬度等等(headwidth
表示箭頭寬度,width
表示箭身的寬度)。畫出來的圖如下所示:
關(guān)于matplotlib繪圖,我在本篇博客中先總結(jié)這么多。當(dāng)然,正像我開頭說的那樣,繪圖的知識點很雜,很多,幾乎不可能全部覆蓋到,暫時也只是將一些我現(xiàn)在能想到的,常用的操作做一個簡單的介紹。本文會保持持續(xù)更新。
轉(zhuǎn)載至[添加鏈接描述](https://blog.csdn.net/guoziqing506/article/details/78975150)