溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Python中怎么利用matplotlib實現(xiàn)繪圖可視化

發(fā)布時間:2021-07-10 13:54:40 來源:億速云 閱讀:198 作者:Leah 欄目:大數(shù)據(jù)

Python中怎么利用matplotlib實現(xiàn)繪圖可視化,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

matplotlib的通常引入約定是:

In [11]: import matplotlib.pyplot as plt

在Jupyter中運行%matplotlib notebook(或在IPython中運行%matplotlib),就可以創(chuàng)建一個簡單的圖形。如果一切設(shè)置正確,會看到圖9-1:

In [12]: import numpy as np

In [13]: data = np.arange(10)

In [14]: data
Out[14]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [15]: plt.plot(data)

雖然seaborn這樣的庫和pandas的內(nèi)置繪圖函數(shù)能夠處理許多普通的繪圖任務(wù),但如果需要自定義一些高級功能的話就必須學(xué)習(xí)matplotlib API。

?

筆記:雖然本書沒有詳細地討論matplotlib的各種功能,但足以將你引入門。matplotlib的示例庫和文檔是學(xué)習(xí)高級特性的最好資源。

?

 

1.1 Figure和Subplot

matplotlib的圖像都位于Figure對象中。你可以用plt.figure創(chuàng)建一個新的Figure:

In [16]: fig = plt.figure()

如果用的是IPython,這時會彈出一個空窗口,但在Jupyter中,必須再輸入更多命令才能看到。plt.figure有一些選項,特別是figsize,它用于確保當(dāng)圖片保存到磁盤時具有一定的大小和縱橫比。

不能通過空Figure繪圖。必須用add_subplot創(chuàng)建一個或多個subplot才行:

In [17]: ax1 = fig.add_subplot(2, 2, 1)

這條代碼的意思是:圖像應(yīng)該是2×2的(即最多4張圖),且當(dāng)前選中的是4個subplot中的第一個(編號從1開始)。如果再把后面兩個subplot也創(chuàng)建出來,最終得到的圖像如圖9-2所示:

In [18]: ax2 = fig.add_subplot(2, 2, 2)

In [19]: ax3 = fig.add_subplot(2, 2, 3)

?

提示:使用Jupyter notebook有一點不同,即每個小窗重新執(zhí)行后,圖形會被重置。因此,對于復(fù)雜的圖形,,你必須將所有的繪圖命令存在一個小窗里。

?

這里,我們運行同一個小窗里的所有命令:

fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)

如果這時執(zhí)行一條繪圖命令(如plt.plot([1.5, 3.5, -2, 1.6])),matplotlib就會在最后一個用過的subplot(如果沒有則創(chuàng)建一個)上進行繪制,隱藏創(chuàng)建figure和subplot的過程。因此,如果我們執(zhí)行下列命令,你就會得到如圖9-3所示的結(jié)果:

In [20]: plt.plot(np.random.randn(50).cumsum(), 'k--')

Python中怎么利用matplotlib實現(xiàn)繪圖可視化

"k--"是一個線型選項,用于告訴matplotlib繪制黑色虛線圖。上面那些由fig.add_subplot所返回的對象是AxesSubplot對象,直接調(diào)用它們的實例方法就可以在其它空著的格子里面畫圖了,如圖9-4所示:

In [21]: ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)

In [22]: ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))

你可以在matplotlib的文檔中找到各種圖表類型。

創(chuàng)建包含subplot網(wǎng)格的figure是一個非常常見的任務(wù),matplotlib有一個更為方便的方法plt.subplots,它可以創(chuàng)建一個新的Figure,并返回一個含有已創(chuàng)建的subplot對象的NumPy數(shù)組:

In [24]: fig, axes = plt.subplots(2, 3)

In [25]: axes
Out[25]: 
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7fb626374048>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7fb62625db00>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7fb6262f6c88>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x7fb6261a36a0>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7fb626181860>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7fb6260fd4e0>]], dtype
=object)

這是非常實用的,因為可以輕松地對axes數(shù)組進行索引,就好像是一個二維數(shù)組一樣,例如axes[0,1]。你還可以通過sharex和sharey指定subplot應(yīng)該具有相同的X軸或Y軸。在比較相同范圍的數(shù)據(jù)時,這也是非常實用的,否則,matplotlib會自動縮放各圖表的界限。有關(guān)該方法的更多信息,請參見表9-1。

Python中怎么利用matplotlib實現(xiàn)繪圖可視化

1.2 調(diào)整subplot周圍的間距

默認情況下,matplotlib會在subplot外圍留下一定的邊距,并在subplot之間留下一定的間距。間距跟圖像的高度和寬度有關(guān),因此,如果你調(diào)整了圖像大小(不管是編程還是手工),間距也會自動調(diào)整。利用Figure的subplots_adjust方法可以輕而易舉地修改間距,此外,它也是個頂級函數(shù):

subplots_adjust(left=None, bottom=None, right=None, top=None,
                wspace=None, hspace=None)

wspace和hspace用于控制寬度和高度的百分比,可以用作subplot之間的間距。下面是一個簡單的例子,其中我將間距收縮到了0(如圖9-5所示):

fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
for i in range(2):
    for j in range(2):
        axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5)
plt.subplots_adjust(wspace=0, hspace=0)

不難看出,其中的軸標簽重疊了。matplotlib不會檢查標簽是否重疊,所以對于這種情況,你只能自己設(shè)定刻度位置和刻度標簽。后面幾節(jié)將會詳細介紹該內(nèi)容。

1.3 顏色、標記和線型

matplotlib的plot函數(shù)接受一組X和Y坐標,還可以接受一個表示顏色和線型的字符串縮寫。例如,要根據(jù)x和y繪制綠色虛線,你可以執(zhí)行如下代碼:

ax.plot(x, y, 'g--')

這種在一個字符串中指定顏色和線型的方式非常方便。在實際中,如果你是用代碼繪圖,你可能不想通過處理字符串來獲得想要的格式。通過下面這種更為明確的方式也能得到同樣的效果:

ax.plot(x, y, linestyle='--', color='g')

常用的顏色可以使用顏色縮寫,你也可以指定顏色碼(例如,'#CECECE')。你可以通過查看plot的文檔字符串查看所有線型的合集(在IPython和Jupyter中使用plot?)。

線圖可以使用標記強調(diào)數(shù)據(jù)點。因為matplotlib可以創(chuàng)建連續(xù)線圖,在點之間進行插值,因此有時可能不太容易看出真實數(shù)據(jù)點的位置。標記也可以放到格式字符串中,但標記類型和線型必須放在顏色后面(見圖9-6):

In [30]: from numpy.random import randn

In [31]: plt.plot(randn(30).cumsum(), 'ko--')

Python中怎么利用matplotlib實現(xiàn)繪圖可視化

還可以將其寫成更為明確的形式:

plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')

在線型圖中,非實際數(shù)據(jù)點默認是按線性方式插值的??梢酝ㄟ^drawstyle選項修改(見圖9-7):

In [33]: data = np.random.randn(30).cumsum()

In [34]: plt.plot(data, 'k--', label='Default')
Out[34]: [<matplotlib.lines.Line2D at 0x7fb624d86160>]

In [35]: plt.plot(data, 'k-', drawstyle='steps-post', label='steps-post')
Out[35]: [<matplotlib.lines.Line2D at 0x7fb624d869e8>]

In [36]: plt.legend(loc='best')

你可能注意到運行上面代碼時有輸出<matplotlib.lines.Line2D at ...>。matplotlib會返回引用了新添加的子組件的對象。大多數(shù)時候,你可以放心地忽略這些輸出。這里,因為我們傳遞了label參數(shù)到plot,我們可以創(chuàng)建一個plot圖例,指明每條使用plt.legend的線。

?

筆記:你必須調(diào)用plt.legend(或使用ax.legend,如果引用了軸的話)來創(chuàng)建圖例,無論你繪圖時是否傳遞label標簽選項。

?

1.4 刻度、標簽和圖例

對于大多數(shù)的圖表裝飾項,其主要實現(xiàn)方式有二:

  • (1)使用過程型的pyplot接口(例如,matplotlib.pyplot)

  • (2)更為面向?qū)ο蟮脑鷐atplotlib API。

pyplot接口的設(shè)計目的就是交互式使用,含有諸如xlim、xticks和xticklabels之類的方法。它們分別控制圖表的范圍、刻度位置、刻度標簽等。其使用方式有以下兩種:

  • 調(diào)用時不帶參數(shù),則返回當(dāng)前的參數(shù)值(例如,plt.xlim()返回當(dāng)前的X軸繪圖范圍)。

  • 調(diào)用時帶參數(shù),則設(shè)置參數(shù)值(例如,plt.xlim([0,10])會將X軸的范圍設(shè)置為0到10)。

所有這些方法都是對當(dāng)前或最近創(chuàng)建的AxesSubplot起作用的。它們各自對應(yīng)subplot對象上的兩個方法,以xlim為例,就是ax.get_xlim和ax.set_xlim。我更喜歡使用subplot的實例方法(因為我喜歡明確的事情,而且在處理多個subplot時這樣也更清楚一些)。當(dāng)然你完全可以選擇自己覺得方便的那個。

1.5 設(shè)置標題、軸標簽、刻度以及刻度標簽

為了說明自定義軸,我將創(chuàng)建一個簡單的圖像并繪制一段隨機漫步(如圖9-8所示):

In [37]: fig = plt.figure()

In [38]: ax = fig.add_subplot(1, 1, 1)

In [39]: ax.plot(np.random.randn(1000).cumsum())

Python中怎么利用matplotlib實現(xiàn)繪圖可視化

要改變x軸刻度,最簡單的辦法是使用set_xticks和set_xticklabels。前者告訴matplotlib要將刻度放在數(shù)據(jù)范圍中的哪些位置,默認情況下,這些位置也就是刻度標簽。但我們可以通過set_xticklabels將任何其他的值用作標簽:

In [40]: ticks = ax.set_xticks([0, 250, 500, 750, 1000])

In [41]: labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'],
   ....:                             rotation=30, fontsize='small')

rotation選項設(shè)定x刻度標簽傾斜30度。最后,再用set_xlabel為X軸設(shè)置一個名稱,并用set_title設(shè)置一個標題(見圖9-9的結(jié)果):

In [42]: ax.set_title('My first matplotlib plot')
Out[42]: <matplotlib.text.Text at 0x7fb624d055f8>

In [43]: ax.set_xlabel('Stages')

Y軸的修改方式與此類似,只需將上述代碼中的x替換為y即可。軸的類有集合方法,可以批量設(shè)定繪圖選項。前面的例子,也可以寫為:

props = {
    'title': 'My first matplotlib plot',
    'xlabel': 'Stages'
}
ax.set(**props)

1.6 添加圖例

圖例(legend)是另一種用于標識圖表元素的重要工具。添加圖例的方式有多種。最簡單的是在添加subplot的時候傳入label參數(shù):

In [44]: from numpy.random import randn

In [45]: fig = plt.figure(); ax = fig.add_subplot(1, 1, 1)

In [46]: ax.plot(randn(1000).cumsum(), 'k', label='one')
Out[46]: [<matplotlib.lines.Line2D at 0x7fb624bdf860>]

In [47]: ax.plot(randn(1000).cumsum(), 'k--', label='two')
Out[47]: [<matplotlib.lines.Line2D at 0x7fb624be90f0>]

In [48]: ax.plot(randn(1000).cumsum(), 'k.', label='three')
Out[48]: [<matplotlib.lines.Line2D at 0x7fb624be9160>]

在此之后,你可以調(diào)用ax.legend()或plt.legend()來自動創(chuàng)建圖例(結(jié)果見圖9-10):

In [49]: ax.legend(loc='best')

Python中怎么利用matplotlib實現(xiàn)繪圖可視化

legend方法有幾個其它的loc位置參數(shù)選項。請查看文檔字符串(使用ax.legend?)。

loc告訴matplotlib要將圖例放在哪。如果你不是吹毛求疵的話,"best"是不錯的選擇,因為它會選擇最不礙事的位置。要從圖例中去除一個或多個元素,不傳入label或傳入label='_nolegend_'即可。

1.7 注解以及在Subplot上繪圖

除標準的繪圖類型,你可能還希望繪制一些子集的注解,可能是文本、箭頭或其他圖形等。注解和文字可以通過text、arrow和annotate函數(shù)進行添加。text可以將文本繪制在圖表的指定坐標(x,y),還可以加上一些自定義格式:

ax.text(x, y, 'Hello world!',
        family='monospace', fontsize=10)

注解中可以既含有文本也含有箭頭。例如,我們根據(jù)最近的標準普爾500指數(shù)價格(來自Yahoo!Finance)繪制一張曲線圖,并標出2008年到2009年金融危機期間的一些重要日期。你可以在Jupyter notebook的一個小窗中試驗這段代碼(圖9-11是結(jié)果):

from datetime import datetime

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

data = pd.read_csv('examples/spx.csv', index_col=0, parse_dates=True)
spx = data['SPX']

spx.plot(ax=ax, style='k-')

crisis_data = [
    (datetime(2007, 10, 11), 'Peak of bull market'),
    (datetime(2008, 3, 12), 'Bear Stearns Fails'),
    (datetime(2008, 9, 15), 'Lehman Bankruptcy')
]

for date, label in crisis_data:
    ax.annotate(label, xy=(date, spx.asof(date) + 75),
                xytext=(date, spx.asof(date) + 225),
                arrowprops=dict(facecolor='black', headwidth=4, width=2,
                                headlength=4),
                horizontalalignment='left', verticalalignment='top')

# Zoom in on 2007-2010
ax.set_xlim(['1/1/2007', '1/1/2011'])
ax.set_ylim([600, 1800])

ax.set_title('Important dates in the 2008-2009 financial crisis')

這張圖中有幾個重要的點要強調(diào):ax.annotate方法可以在指定的x和y坐標軸繪制標簽。我們使用set_xlim和set_ylim人工設(shè)定起始和結(jié)束邊界,而不使用matplotlib的默認方法。最后,用ax.set_title添加圖標標題。

更多有關(guān)注解的示例,請訪問matplotlib的在線示例庫。

圖形的繪制要麻煩一些。matplotlib有一些表示常見圖形的對象。這些對象被稱為塊(patch)。其中有些(如Rectangle和Circle),可以在matplotlib.pyplot中找到,但完整集合位于matplotlib.patches。

要在圖表中添加一個圖形,你需要創(chuàng)建一個塊對象shp,然后通過ax.add_patch(shp)將其添加到subplot中(如圖9-12所示):

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

rect = plt.Rectangle((0.2, 0.75), 0.4, 0.15, color='k', alpha=0.3)
circ = plt.Circle((0.7, 0.2), 0.15, color='b', alpha=0.3)
pgon = plt.Polygon([[0.15, 0.15], [0.35, 0.4], [0.2, 0.6]],
                   color='g', alpha=0.5)

ax.add_patch(rect)
ax.add_patch(circ)
ax.add_patch(pgon)

Python中怎么利用matplotlib實現(xiàn)繪圖可視化

「如果查看許多常見圖表對象的具體實現(xiàn)代碼,你就會發(fā)現(xiàn)它們其實就是由塊patch組裝而成的。」

1.8 將圖表保存到文件

利用plt.savefig可以將當(dāng)前圖表保存到文件。該方法相當(dāng)于Figure對象的實例方法savefig。例如,要將圖表保存為SVG文件,你只需輸入:

plt.savefig('figpath.svg')

文件類型是通過文件擴展名推斷出來的。因此,如果你使用的是.pdf,就會得到一個PDF文件。我在發(fā)布圖片時最常用到兩個重要的選項是dpi(控制“每英寸點數(shù)”分辨率)和bbox_inches(可以剪除當(dāng)前圖表周圍的空白部分)。要得到一張帶有最小白邊且分辨率為400DPI的PNG圖片,你可以:

plt.savefig('figpath.png', dpi=400, bbox_inches='tight')

savefig并非一定要寫入磁盤,也可以寫入任何文件型的對象,比如BytesIO:

from io import BytesIO
buffer = BytesIO()
plt.savefig(buffer)
plot_data = buffer.getvalue()

看完上述內(nèi)容,你們掌握Python中怎么利用matplotlib實現(xiàn)繪圖可視化的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI