使用 Matplotlib 進行 Python 繪圖指南

      網友投稿 1181 2025-03-31

      目錄


      Why Can Matplotlib Be Confusing?

      Pylab: What Is It, and Should I Use It?

      The Matplotlib Object Hierarchy

      Stateful Versus Stateless Approaches

      Understanding plt.subplots() Notation

      The “Figures” Behind The Scenes

      A Burst of Color: imshow() and matshow()

      Plotting in Pandas

      Wrapping Up

      More Resources

      Appendix A: Configuration and Styling

      Appendix B: Interactive Mode

      一張圖片值一千字,而使用 Python 的matplotlib庫,幸運的是,只需不到一千字的代碼就可以創建出具有生產質量的圖形。

      然而,matplotlib 也是一個龐大的庫,讓一個情節看起來恰到好處通常是通過反復試驗來實現的。在 matplotlib 中使用 one-liners 生成基本繪圖相當簡單,但巧妙地控制庫中剩余的 98% 可能會令人生畏。

      本文是 matplotlib 的初級到中級演練,將理論與示例相結合。雖然通過實例學習可以非常有見地,但它甚至有助于對圖書館的內部運作和布局有一個表面的理解。

      以下是我們將介紹的內容:

      Pylab 和 pyplot:哪個是哪個?

      matplotlib 設計的關鍵概念

      理解?plt.subplots()

      使用 matplotlib 可視化數組

      使用 pandas + matplotlib 組合繪圖

      本文假設用戶對 NumPy 有一點了解。我們將主要使用該numpy.random模塊生成“玩具”數據,從不同的統計分布中抽取樣本。

      如果您尚未安裝 matplotlib,請在繼續之前查看此處的演練。

      Why Can Matplotlib Be Confusing?

      學習 matplotlib 有時可能是一個令人沮喪的過程。問題不在于缺少 matplotlib 的文檔:文檔實際上非常廣泛。但以下問題可能會帶來一些挑戰:

      庫本身很大,大約有 70,000 行代碼。

      Matplotlib 擁有多種不同的界面(構建圖形的方式),并且能夠與少數不同的后端進行交互。(后端處理圖表實際呈現的過程,而不僅僅是內部結構化。)

      雖然它很全面,但 matplotlib 自己的一些公共文檔已經嚴重過時了。該庫仍在不斷發展,許多在網上流傳的舊示例在其現代版本中可能會減少 70% 的代碼行。

      因此,在我們進入任何華麗的例子之前,掌握 matplotlib 設計的核心概念是很有用的。

      Pylab: What Is It, and Should I Use It?

      讓我們從一段歷史開始:神經生物學家 John D. Hunter 于 2003 年左右開始開發 matplotlib,最初的靈感來自于模擬 Mathworks 的MATLAB軟件中的命令。John 在 2012 年 44 歲時不幸去世,matplotlib 現在是一個成熟的社區項目,由許多其他人開發和維護。(約翰給一個談話約matplotlib在2012年SciPy的會議,這是值得關注的變化。)

      MATLAB 的一項相關特性是其全局樣式。導入的 Python 概念在 MATLAB 中并沒有大量使用,并且 MATLAB 的大部分功能在頂層對用戶來說是現成的。

      知道 matplotlib 起源于 MATLAB 有助于解釋為什么 pylab 存在。pylab 是 matplotlib 庫中的一個模塊,旨在模仿 MATLAB 的全局風格。它的存在只是為了將 NumPy 和 matplotlib 中的許多函數和類帶入命名空間,使不習慣需要import語句的前 MATLAB 用戶輕松過渡。

      前 MATLAB 轉換者(我保證他們都是好人,我保證!)喜歡這個功能,因為使用from pylab import *,他們可以像在 MATLAB 中一樣簡單地調用plot()或array()直接調用。

      這里的問題對一些 Python 用戶來說可能很明顯:from pylab import *在會話或腳本中使用通常是不好的做法。Matplotlib 現在在其自己的教程中直接建議不要這樣做:

      “由于歷史原因,[pylab] 仍然存在,但強烈建議不要使用。它使用會影響 Python 內置函數的函數污染命名空間,并可能導致難以跟蹤的錯誤。要在沒有導入的情況下獲得 IPython 集成,最好使用%matplotlib魔法。”?[來源]

      在內部,在簡短的 pylab源代碼中隱藏了大量潛在的沖突導入。事實上,使用ipython --pylab(從終端/命令行)或%pylab(從 IPython/Jupyter 工具)只是from pylab import *在幕后調用。

      底線是matplotlib 已經放棄了這個方便的模塊,現在明確建議不要使用 pylab,使事情更符合 Python 的一個關鍵概念:顯式優于隱式。

      不需要 pylab,我們通常可以只使用一個規范導入:

      >>>

      >>> import matplotlib.pyplot as plt

      在此過程中,我們還導入 NumPy,稍后我們將使用它來生成數據,并調用np.random.seed()可重現(偽)隨機數據的示例:

      >>>

      >>> import numpy as np >>> np.random.seed(444)

      The Matplotlib Object Hierarchy

      matplotlib 的一個重要概念是它的對象層次結構。

      如果您已經學習過任何介紹性的 matplotlib 教程,那么您可能已經調用過類似plt.plot([1, 2, 3]).?這個單行隱藏了一個事實,即繪圖實際上是嵌套 Python 對象的層次結構。這里的“層次結構”意味著每個圖下面都有一個 matplotlib 對象的樹狀結構。

      甲Figure對象為matplotlib圖形,它可以包含多個最外容器Axes對象。混淆的一個來源是名稱:anAxes實際上轉化為我們認為的單個情節或圖形(而不是我們所期望的“軸”的復數形式)。

      您可以將Figure對象視為裝有一個或多個Axes(實際繪圖)的盒狀容器。Axes層次結構中的下方是較小的對象,例如刻度線、單行、圖例和文本框。圖表的幾乎每個“元素”都是它自己的可操作 Python 對象,一直到刻度和標簽:

      這是此層次結構的示例圖。如果您不完全熟悉這種表示法,請不要擔心,我們將在稍后介紹:

      >>>

      >>> fig, _ = plt.subplots() >>> type(fig)

      上面,我們創建了兩個變量有plt.subplots()。第一個是頂級Figure對象。第二個是我們還不需要的“一次性”變量,用下劃線表示。使用屬性表示法,很容易向下遍歷圖形層次結構并查看第一個 Axes 對象的 y 軸的第一個刻度:

      >>>

      >>> one_tick = fig.axes[0].yaxis.get_major_ticks()[0] >>> type(one_tick)

      上面,fig(一個Figure類實例)有多個Axes(一個列表,我們取第一個元素)。每個Axes都有一個yaxisand?xaxis,每個都有一個“主要刻度”的集合,我們抓住第一個。

      Matplotlib 將其呈現為人體解剖結構,而不是明確的層次結構:

      (在真正的 matplotlib 樣式中,上圖是在此處的 matplotlib 文檔中創建的。)

      Stateful Versus Stateless Approaches

      好吧,在我們開始討論閃亮的可視化之前,我們還需要更多的理論知識:有狀態(基于狀態,狀態機)和無狀態(面向對象,OO)接口之間的區別。

      上面,我們曾經import matplotlib.pyplot as plt從 matplotlib 導入 pyplot 模塊并將其命名為plt.

      pyplot 中的幾乎所有函數,例如plt.plot(),都隱式地引用現有的當前圖形和當前軸,或者如果不存在則重新創建它們。隱藏在 matplotlib 文檔中的是這個有用的片段:

      “[使用 pyplot],使用簡單的函數將繪圖元素(線條、圖像、文本等)添加到當前圖形中的當前軸。”?【強調】

      鐵桿前 MATLAB 用戶可能會選擇這樣說:“plt.plot()是一個隱式跟蹤當前數字的狀態機接口!”?在英語中,這意味著:

      有狀態接口使用plt.plot()和其他頂級 pyplot 函數進行調用。在給定時間,您只操作一個圖形或軸,您無需明確引用它。

      直接修改底層對象是面向對象的方法。我們通常通過調用一個Axes對象的方法來做到這一點,該對象是代表一個情節本身的對象。

      從高層次來看,此過程的流程如下所示:

      將這些結合在一起,pyplot 中的大多數函數也作為matplotlib.axes.Axes類的方法存在。

      通過在引擎蓋下偷看,這更容易看到。plt.plot()可以歸結為五行左右的代碼:

      >>>

      # matplotlib/pyplot.py >>> def plot(*args, **kwargs): ... """An abridged version of plt.plot().""" ... ax = plt.gca() ... return ax.plot(*args, **kwargs) >>> def gca(**kwargs): ... """Get the current Axes of the current Figure.""" ... return plt.gcf().gca(**kwargs)

      調用plt.plot()只是獲取當前 Figure 的當前 Axes 然后調用其plot()方法的便捷方式。這就是有狀態接口總是“隱式跟蹤”它想要引用的圖的斷言的意思。

      pyplot 是一批函數的所在地,這些函數實際上只是圍繞 matplotlib 的面向對象接口的包裝。例如,with?plt.title(),OO 方法中有相應的 setter 和 getter 方法,ax.set_title()以及ax.get_title()。(getter 和 setter 的使用在Java等語言中更受歡迎,但它是 matplotlib 的 OO 方法的一個關鍵特性。)

      呼叫plt.title()被翻譯成這一行:gca().set_title(s, *args, **kwargs)。這是在做什么:

      gca()?抓取當前軸并返回它。

      set_title()是設置該 Axes 對象的標題的 setter 方法。這里的“方便”是我們不需要用 明確指定任何 Axes 對象plt.title()。

      類似地,如果您花一些時間查看諸如plt.grid(),plt.legend()和 之類的頂級函數的源代碼plt.ylabels(),您會注意到它們都遵循相同的結構,即委托給當前 Axes withgca()然后調用當前 Axes 的某些方法軸。(這是底層的面向對象方法!)

      Understanding?plt.subplots()?Notation

      好了,理論夠了。現在,我們已準備好將所有內容聯系在一起并進行一些繪圖。從現在開始,我們將主要依賴無狀態(面向對象)方法,這種方法更具可定制性,并且隨著圖形變得更加復雜而派上用場。

      在 OO 方法下創建具有單個軸的圖形的規定方法是(不太直觀)使用plt.subplots().?這確實是 OO 方法唯一一次使用pyplot, 創建圖形和軸:

      >>>

      >>> fig, ax = plt.subplots()

      上面,我們利用可迭代解包為 的兩個結果中的每一個分配了一個單獨的變量plt.subplots()。請注意,我們沒有向subplots()此處傳遞參數。默認調用是subplots(nrows=1, ncols=1)。因此,ax是單個AxesSubplot對象:

      >>>

      >>> type(ax)

      我們可以調用它的實例方法來操作繪圖,類似于我們調用 pyplots 函數的方式。讓我們用三個時間序列的堆積面積圖來說明:

      >>>

      >>> rng = np.arange(50) >>> rnd = np.random.randint(0, 10, size=(3, rng.size)) >>> yrs = 1950 + rng >>> fig, ax = plt.subplots(figsize=(5, 3)) >>> ax.stackplot(yrs, rng + rnd, labels=['Eastasia', 'Eurasia', 'Oceania']) >>> ax.set_title('Combined debt growth over time') >>> ax.legend(loc='upper left') >>> ax.set_ylabel('Total debt') >>> ax.set_xlim(xmin=yrs[0], xmax=yrs[-1]) >>> fig.tight_layout()

      這是上面發生的事情:

      在創建了三個隨機時間序列后,我們定義了一個fig包含一個軸(圖,ax)的圖形 (?)。

      我們ax直接調用方法來創建堆積面積圖并添加圖例、標題和 y 軸標簽。在面向對象的方法下,很明顯,所有這些都是ax.

      tight_layout()?適用于 Figure 對象作為一個整體來清理空白填充。

      讓我們看一個在一個圖中包含多個子圖(軸)的示例,繪制從離散均勻分布中繪制的兩個相關數組:

      >>>

      >>> x = np.random.randint(low=1, high=11, size=50) >>> y = x + np.random.randint(1, 5, size=x.size) >>> data = np.column_stack((x, y)) >>> fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, ... figsize=(8, 4)) >>> ax1.scatter(x=x, y=y, marker='o', c='r', edgecolor='b') >>> ax1.set_title('Scatter: $x$ versus $y$') >>> ax1.set_xlabel('$x$') >>> ax1.set_ylabel('$y$') >>> ax2.hist(data, bins=np.arange(data.min(), data.max()), ... label=('x', 'y')) >>> ax2.legend(loc=(0.65, 0.8)) >>> ax2.set_title('Frequencies of $x$ and $y$') >>> ax2.yaxis.tick_right()

      在這個例子中還有一些事情要做:

      因為我們正在創建一個“1x2”圖形,返回的結果plt.subplots(1, 2)現在是一個 Figure 對象和一個 Axes 對象的 NumPy 數組。(您可以使用fig, axs = plt.subplots(1, 2)并查看 來檢查它axs。)

      我們單獨處理ax1和處理ax2,這很難用有狀態的方法來處理。最后一行很好地說明了對象層次結構,我們正在修改yaxis屬于第二個軸的對象,將其刻度和刻度標簽放在右側。

      美元符號內的文本利用TeX 標記將變量置于斜體中。

      請記住,多個軸可以包含在或“屬于”給定圖形中。在上面的例子中,fig.axes給我們一個所有 Axes 對象的列表:

      >>>

      >>> (fig.axes[0] is ax1, fig.axes[1] is ax2) (True, True)

      (fig.axes是小寫,而不是大寫。不可否認,術語有點令人困惑。)

      更進一步,我們也可以創建一個包含 2x2Axes對象網格的圖形:

      >>>

      使用 Matplotlib 進行 Python 繪圖指南

      >>> fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(7, 7))

      現在,什么是ax?它不再是單個Axes,而是它們的二維 NumPy 數組:

      >>>

      >>> type(ax) numpy.ndarray >>> ax array([[, ], [, ]], dtype=object) >>> ax.shape (2, 2)

      文檔字符串重申了這一點:

      “如果創建了多個子圖,則ax可以是單個matplotlib.axes.Axes對象或一組Axes對象。”

      我們現在需要對其中的每一個調用繪圖方法Axes(但不是 NumPy 數組,在這種情況下它只是一個容器)。解決此問題的常見方法是在將數組展平為一維后使用可迭代解包:

      >>>

      >>> fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(7, 7)) >>> ax1, ax2, ax3, ax4 = ax.flatten() # flatten a 2d NumPy array to 1d

      我們也可以用 來做到這一點((ax1, ax2), (ax3, ax4)) = ax,但第一種方法往往更靈活。

      為了說明一些更高級的功能,次要情節,讓我們脫離了一個壓縮的tar歸檔文件中提取一些宏觀經濟加州房市數據,使用io,tarfile以及urllib從Python的標準庫。

      >>>

      >>> from io import BytesIO >>> import tarfile >>> from urllib.request import urlopen >>> url = 'http://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.tgz' >>> b = BytesIO(urlopen(url).read()) >>> fpath = 'CaliforniaHousing/cal_housing.data' >>> with tarfile.open(mode='r', fileobj=b) as archive: ... housing = np.loadtxt(archive.extractfile(fpath), delimiter=',')

      y使用統計術語,下面的“響應”變量是一個地區的平均房屋價值。pop和age分別是該地區的人口和平均房屋年齡:

      >>>

      >>> y = housing[:, -1] >>> pop, age = housing[:, [4, 7]].T

      接下來讓我們定義一個“輔助函數”,它將文本框放置在繪圖內并充當“繪圖內標題”:

      >>>

      >>> def add_titlebox(ax, text): ... ax.text(.55, .8, text, ... horizontalalignment='center', ... transform=ax.transAxes, ... bbox=dict(facecolor='white', alpha=0.6), ... fontsize=12.5) ... return ax

      我們準備做一些繪圖。Matplotlib 的gridspec模塊允許更多的子圖定制。pyplotsubplot2grid()與這個模塊很好地交互。假設我們要創建這樣的布局:

      上面,我們實際擁有的是一個 3x2 的網格。ax1是ax2/的高度和寬度的兩倍ax3,這意味著它占據兩列和兩行。

      的第二個參數subplot2grid()是坐標軸在網格中的(行、列)位置:

      >>>

      >>> gridsize = (3, 2) >>> fig = plt.figure(figsize=(12, 8)) >>> ax1 = plt.subplot2grid(gridsize, (0, 0), colspan=2, rowspan=2) >>> ax2 = plt.subplot2grid(gridsize, (2, 0)) >>> ax3 = plt.subplot2grid(gridsize, (2, 1))

      現在,我們可以照常進行,分別修改每個軸:

      >>>

      >>> ax1.set_title('Home value as a function of home age & area population', ... fontsize=14) >>> sctr = ax1.scatter(x=age, y=pop, c=y, cmap='RdYlGn') >>> plt.colorbar(sctr, ax=ax1, format='$%d') >>> ax1.set_yscale('log') >>> ax2.hist(age, bins='auto') >>> ax3.hist(pop, bins='auto', log=True) >>> add_titlebox(ax2, 'Histogram: home age') >>> add_titlebox(ax3, 'Histogram: area population (log scl.)')

      上面,colorbar()(與之前的 ColorMap 不同)直接在 Figure 上調用,而不是在 Axes 上調用。它的第一個參數使用 Matplotlib 的,.scatter()并且是 的結果ax1.scatter(),它用作 y 值到 ColorMap 的映射。

      從視覺上看,當我們沿 y 軸上下移動時,顏色(y 變量)沒有太大差異,這表明房屋年齡似乎是房屋價值的更強決定因素。

      The “Figures” Behind The Scenes

      每次調用plt.subplots()或不常用的plt.figure()(創建一個沒有軸的圖形)時,您都在創建一個新的圖形對象,matplotlib 偷偷地將它保存在內存中。早些時候,我們提到了當前圖形和當前軸的概念。默認情況下,這些是最近創建的 Figure 和 Axes,我們可以使用內置函數id()顯示它們以顯示對象在內存中的地址:

      >>>

      >>> fig1, ax1 = plt.subplots() >>> id(fig1) 4525567840 >>> id(plt.gcf()) # `fig1` is the current figure. 4525567840 >>> fig2, ax2 = plt.subplots() >>> id(fig2) == id(plt.gcf()) # The current figure has changed to `fig2`. True

      (我們也可以在這里使用內置is運算符。)

      經過上述例程,當前圖形為fig2,最近創建的圖形。然而,這兩個數字仍然在內存中徘徊,每個數字都有一個對應的 ID 號(1-indexed,在 MATLAB 風格中):

      >>>

      >>> plt.get_fignums() [1, 2]

      獲取所有數字本身的一種有用方法是映射plt.figure()到這些整數中的每一個:

      >>>

      >>> def get_all_figures(): ... return [plt.figure(i) for i in plt.get_fignums()] >>> get_all_figures() [, ]

      如果在創建一組圖形時運行腳本,請注意這一點。您需要在使用后明確關閉它們中的每一個以避免MemoryError.?自行plt.close()關閉當前圖形,plt.close(num)關閉圖形編號num,并plt.close('all')關閉所有圖形窗口:

      >>>

      >>> plt.close('all') >>> get_all_figures() []

      A Burst of Color:?imshow()?and?matshow()

      雖然ax.plot()是 Axes 上最常見的繪圖方法之一,但還有許多其他方法。(我們在ax.stackplot()上面使用過。您可以在此處找到完整列表。)

      大量使用的方法是imshow()and?matshow(),后者是前者的包裝器。這些在任何時候都非常有用,可以將原始數值數組可視化為彩色網格。

      首先,讓我們用一些奇特的 NumPy 索引創建兩個不同的網格:

      >>>

      >>> x = np.diag(np.arange(2, 12))[::-1] >>> x[np.diag_indices_from(x[::-1])] = np.arange(2, 12) >>> x2 = np.arange(x.size).reshape(x.shape)

      接下來,我們可以將這些映射到它們的圖像表示。在這種特定情況下,我們通過使用字典理解并將結果傳遞給“關閉”所有軸標簽和刻度ax.tick_params():

      >>>

      >>> sides = ('left', 'right', 'top', 'bottom') >>> nolabels = {s: False for s in sides} >>> nolabels.update({'label%s' % s: False for s in sides}) >>> print(nolabels) {'left': False, 'right': False, 'top': False, 'bottom': False, 'labelleft': False, 'labelright': False, 'labeltop': False, 'labelbottom': False}

      然后,我們可以使用上下文管理器禁用網格,并調用matshow()每個軸。最后,我們需要將顏色條放在fig.?為此,我們可以使用 matplotlib 深處的一些深奧函數:

      >>>

      >>> from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable >>> with plt.rc_context(rc={'axes.grid': False}): ... fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4)) ... ax1.matshow(x) ... img2 = ax2.matshow(x2, cmap='RdYlGn_r') ... for ax in (ax1, ax2): ... ax.tick_params(axis='both', which='both', **nolabels) ... for i, j in zip(*x.nonzero()): ... ax1.text(j, i, x[i, j], color='white', ha='center', va='center') ... ... divider = make_axes_locatable(ax2) ... cax = divider.append_axes("right", size='5%', pad=0) ... plt.colorbar(img2, cax=cax, ax=[ax1, ax2]) ... fig.suptitle('Heatmaps with `Axes.matshow`', fontsize=16)

      Plotting in Pandas

      pandas 庫不僅因為支持強大的數據分析,還因為它方便的預制繪圖方法而變得流行。有趣的是,pandas 繪圖方法實際上只是對現有 matplotlib 調用的方便包裝。

      也就是說,plot()pandas 的 Series 和DataFrame上的方法是plt.plot().?例如,提供的一種便利是,如果 DataFrame 的索引由日期組成,則由 Pandas 在gcf().autofmt_xdate()內部調用以獲取當前圖形并很好地自動格式化 x 軸。

      反過來,請記住plt.plot()(基于狀態的方法)隱式地知道當前的圖形和當前的軸,因此熊貓通過擴展遵循基于狀態的方法。

      我們可以通過一些內省來證明這個函數調用的“鏈”。首先,讓我們構建一個普通的熊貓系列,假設我們從一個新的解釋器會話開始:

      >>>

      >>> import pandas as pd >>> s = pd.Series(np.arange(5), index=list('abcde')) >>> ax = s.plot() >>> type(ax) >>> id(plt.gca()) == id(ax) True

      這種內部架構有助于了解何時將 Pandas 繪圖方法與傳統的 matplotlib 調用混合使用,這在下面繪制廣受關注的金融時間序列的移動平均線時完成。ma是一個我們可以調用的pandas系列ma.plot()(pandas方法),然后通過檢索這個調用創建的Axes進行自定義(plt.gca()),供matplotlib參考:

      >>>

      >>> import pandas as pd >>> import matplotlib.transforms as mtransforms >>> url = 'https://fred.stlouisfed.org/graph/fredgraph.csv?id=VIXCLS' >>> vix = pd.read_csv(url, index_col=0, parse_dates=True, na_values='.', ... infer_datetime_format=True, ... squeeze=True).dropna() >>> ma = vix.rolling('90d').mean() >>> state = pd.cut(ma, bins=[-np.inf, 14, 18, 24, np.inf], ... labels=range(4)) >>> cmap = plt.get_cmap('RdYlGn_r') >>> ma.plot(color='black', linewidth=1.5, marker='', figsize=(8, 4), ... label='VIX 90d MA') >>> ax = plt.gca() # Get the current Axes that ma.plot() references >>> ax.set_xlabel('') >>> ax.set_ylabel('90d moving average: CBOE VIX') >>> ax.set_title('Volatility Regime State') >>> ax.grid(False) >>> ax.legend(loc='upper center') >>> ax.set_xlim(xmin=ma.index[0], xmax=ma.index[-1]) >>> trans = mtransforms.blended_transform_factory(ax.transData, ax.transAxes) >>> for i, color in enumerate(cmap([0.2, 0.4, 0.6, 0.8])): ... ax.fill_between(ma.index, 0, 1, where=state==i, ... facecolor=color, transform=trans) >>> ax.axhline(vix.mean(), linestyle='dashed', color='xkcd:dark grey', ... alpha=0.6, label='Full-period mean', marker='')

      上面發生了很多事情:

      ma是 VIX 指數的 90 天移動平均線,衡量近期股票波動的市場預期。state是將移動平均線劃分為不同的狀態狀態。高 VIX 被視為表明市場恐懼程度加劇。

      cmap是一個 ColorMap——一個 matplotlib 對象,它本質上是一個浮點數到 RGBA 顏色的映射。任何顏色圖都可以通過附加來反轉'_r','RdYlGn_r'反轉的紅黃綠顏色圖也是如此。Matplotlib在其文檔中維護了一個方便的ColorMaps視覺參考指南。

      我們在這里發出的唯一真正的熊貓電話是ma.plot().?這在plt.plot()內部調用,因此為了集成面向對象的方法,我們需要使用 獲得對當前 Axes 的顯式引用ax = plt.gca()。

      第二段代碼創建了對應于state.?cmap([0.2, 0.4, 0.6, 0.8])說,“給我們一個 RGBA 序列,用于在 ColorMaps 光譜中第 20、40、60 和 80 個‘百分位數’的顏色。”?enumerate()之所以使用,是因為我們想將每個 RGBA 顏色映射回一個狀態。

      Pandas 還內置了一些更高級的情節(這些情節可以單獨占用整個教程)。然而,所有這些,就像它們更簡單的對應物一樣,在內部依賴于 matplotlib 機制。

      Wrapping Up

      正如上面的一些示例所示,matplotlib 可能是一個技術性的、語法繁重的庫這一事實是無可避免的。創建可用于生產的圖表有時需要半小時的谷歌搜索并結合一大堆線條來微調情節。

      然而,了解 matplotlib 的接口如何交互是一項可以在未來獲得回報的投資。正如 Real Python 自己的 Dan Bader 所建議的那樣,花時間剖析代碼而不是求助于 Stack Overflow“復制面食”解決方案往往是一個更聰明的長期解決方案。當您想將一個情節從簡單的情節變為藝術作品時,堅持面向對象的方法可以節省數小時的挫敗感。

      更多資源

      來自 matplotlib 文檔:

      matplotlib示例索引

      使用常見問題

      該教程頁面,它分為初級,中級和高級部分

      情節的生命周期,涉及面向對象與有狀態的方法

      第三方資源:

      DataCamp 的 matplotlib備忘單

      PLOS 計算生物學:獲得更好數字的十個簡單規則

      Wes McKinney 的Python for Data Analysis第 9 章(繪圖和可視化),第 2 版。

      Ted Petrou 的Pandas Cookbook第 11 章(使用 Matplotlib、Pandas 和 Seaborn 進行可視化)

      SciPy 講義的第 1.4 節(Matplotlib:繪圖)

      該XKCD調色板

      matplotlib外部資源頁面

      Matplotlib、Pylab、Pyplot 等:它們之間有什么區別以及何時使用它們?來自 queirozf.com

      pandas 文檔中的可視化頁面

      其他繪圖庫:

      該seaborn庫,建立在matplotlib的頂部,設計先進的統計圖形,這可能需要長達一整個教程的所有對自己

      Datashader,一個專門針對大型數據集的圖形庫

      來自 matplotlib 文檔的其他第三方包的列表

      Appendix A: Configuration and Styling

      如果您一直在學習本教程,則屏幕上彈出的圖形可能與此處顯示的圖形在風格上有所不同。

      Matplotlib 提供了兩種方法來以統一的方式跨不同的圖配置樣式:

      通過自定義matplotlibrc文件

      通過以交互方式或從.py腳本更改配置參數。

      matplotlibrc 文件(上面的選項 #1)基本上是一個文本文件,指定在 Python 會話之間記住的用戶自定義設置。在 Mac OS X 上,它通常位于~/.matplotlib/matplotlibrc。

      快速提示:?GitHub 是保存配置文件的好地方。我把我的留在這里。只需確保它們不包含個人身份或私人信息,例如密碼或 SSH 私鑰!

      或者,您可以交互地更改配置參數(上面的選項 #2)。當您使用 時import matplotlib.pyplot as plt,您可以訪問一個rcParams類似于 Python 設置字典的對象。所有以“rc”開頭的模塊對象都是與您的繪圖樣式和設置進行交互的一種方式:

      >>>

      >>> [attr for attr in dir(plt) if attr.startswith('rc')] ['rc', 'rcParams', 'rcParamsDefault', 'rc_context', 'rcdefaults']

      這些:

      plt.rcdefaults()從 matplotlib 的內部默認值中恢復 rc 參數,這些參數在plt.rcParamsDefault.?這將恢復(覆蓋)您已經在 matplotlibrc 文件中自定義的任何內容。

      plt.rc()?用于交互設置參數。

      plt.rcParams是一個(可變的)類似字典的對象,可讓您直接操作設置。如果您在 matplotlibrc 文件中有自定義設置,這些將反映在此字典中。

      使用plt.rc()和plt.rcParams,這兩種語法對于調整設置是等效的:

      >>>

      >>> plt.rc('lines', linewidth=2, color='r') # Syntax 1 >>> plt.rcParams['lines.linewidth'] = 2 # Syntax 2 >>> plt.rcParams['lines.color'] = 'r'

      值得注意的是,Figure 類然后使用其中一些作為其默認參數。

      相關地,樣式只是一組預定義的自定義設置。要查看可用樣式,請使用:

      >>>

      >>> plt.style.available ['seaborn-dark', 'seaborn-darkgrid', 'seaborn-ticks', 'fivethirtyeight', 'seaborn-whitegrid', 'classic', '_classic_test', 'fast', 'seaborn-talk', 'seaborn-dark-palette', 'seaborn-bright', 'seaborn-pastel', 'grayscale', 'seaborn-notebook', 'ggplot', 'seaborn-colorblind', 'seaborn-muted', 'seaborn', 'Solarize_Light2', 'seaborn-paper', 'bmh', 'seaborn-white', 'dark_background', 'seaborn-poster', 'seaborn-deep']

      要設置樣式,請撥打以下電話:

      >>>

      >>> plt.style.use('fivethirtyeight')

      您的繪圖現在將煥然一新:

      這個完整的例子可以在這里找到。

      為了獲得靈感,matplotlib 還保留了一些樣式表顯示以供參考。

      Appendix B: Interactive Mode

      在幕后,matplotlib 還與不同的后端進行交互。后端是實際渲染圖表背后的主力軍。(例如,在流行的 Anaconda 發行版中,默認后端是 Qt5Agg。)一些后端是交互式的,這意味著它們會動態更新并在更改時“彈出”給用戶。

      當交互模式默認關閉時,您可以使用plt.rcParams['interactive']或來檢查其狀態plt.isinteractive(),并分別使用plt.ion()和 將其打開和關閉plt.ioff():

      >>>

      >>> plt.rcParams['interactive'] # or: plt.isinteractive() True

      >>>

      >>> plt.ioff() >>> plt.rcParams['interactive'] False

      在一些代碼示例中,您可能會注意到在一段代碼plt.show()的末尾。plt.show()顧名思義,主要目的是在關閉交互模式的情況下運行時實際“顯示”(打開)圖形。換句話說:

      如果交互模式打開,則不需要plt.show(),并且圖像會在您引用它們時自動彈出并更新。

      如果交互模式關閉,您將需要plt.show()顯示圖形并plt.draw()更新繪圖。

      下面,我們確保交互模式關閉,這需要我們plt.show()在構建繪圖本身后調用:

      >>>

      >>> plt.ioff() >>> x = np.arange(-4, 5) >>> y1 = x ** 2 >>> y2 = 10 / (x ** 2 + 1) >>> fig, ax = plt.subplots() >>> ax.plot(x, y1, 'rx', x, y2, 'b+', linestyle='solid') >>> ax.fill_between(x, y1, y2, where=y2>y1, interpolate=True, ... color='green', alpha=0.3) >>> lgnd = ax.legend(['y1', 'y2'], loc='upper center', shadow=True) >>> lgnd.get_frame().set_facecolor('#ffb19a') >>> plt.show()

      值得注意的是,交互模式與您使用的 IDE 無關,或者您是否啟用了諸如jupyter notebook --matplotlib inline或 之類的內聯繪圖%matplotlib。

      Python 數據可視化

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:WPS表格怎樣快速合并兩列內容(wps表格如何兩列文字合并)
      下一篇:停車場智能管理系統排行榜2022最新排名前十對比
      相關文章
      亚洲色在线无码国产精品不卡| 亚洲风情亚Aⅴ在线发布| 国产成人精品日本亚洲11| 国产成人亚洲综合一区| 亚洲国产精品成人AV无码久久综合影院 | 亚洲AV成人片色在线观看高潮| 国产成人综合亚洲绿色| 亚洲男人天堂2017| 亚洲乱码国产一区网址| 亚洲欧洲无码AV不卡在线| 国产成人精品日本亚洲专区6| 亚洲特级aaaaaa毛片| 久久被窝电影亚洲爽爽爽| 亚洲第一网站男人都懂| 亚洲国产成人精品女人久久久 | 蜜芽亚洲av无码一区二区三区| 亚洲色欲或者高潮影院| 亚洲av永久无码精品漫画| 狠狠亚洲狠狠欧洲2019| 国产精品久久久久久亚洲小说 | 亚洲自偷自拍另类图片二区| 亚洲色图.com| 亚洲无吗在线视频| 亚洲va久久久久| 国产AV无码专区亚洲AV麻豆丫 | 亚洲午夜精品在线| 99久久亚洲综合精品成人网| 亚洲AV综合色一区二区三区| 久久久久亚洲AV无码专区首| 亚洲色图.com| 亚洲性色AV日韩在线观看| 亚洲一区精彩视频| 亚洲精品国产首次亮相| 狼人大香伊蕉国产WWW亚洲| 亚洲欧洲中文日韩av乱码| 亚洲成av人片在线观看天堂无码| 2048亚洲精品国产| 亚洲AV综合色区无码一区| 亚洲欧洲日韩综合| 亚洲av无码专区在线观看亚| 亚洲精品自偷自拍无码|