Matplotlib繪製的27個常用圖(附對應程式碼實現)

  • 2019 年 11 月 22 日
  • 筆記

0 共用模組

模組名稱:example_utils.py,裡面包括三個函數,各自功能如下:

import matplotlib.pyplot as plt    # 創建畫圖fig和axes  def setup_axes():      fig, axes = plt.subplots(ncols=3, figsize=(6.5,3))      for ax in fig.axes:          ax.set(xticks=[], yticks=[])      fig.subplots_adjust(wspace=0, left=0, right=0.93)      return fig, axes  # 圖片標題  def title(fig, text, y=0.9):      fig.suptitle(text, size=14, y=y, weight='semibold', x=0.98, ha='right',                   bbox=dict(boxstyle='round', fc='floralwhite', ec='#8B7E66',                             lw=2))  # 為數據添加文本注釋  def label(ax, text, y=0):      ax.annotate(text, xy=(0.5, 0.00), xycoords='axes fraction', ha='center',                  style='italic',                  bbox=dict(boxstyle='round', facecolor='floralwhite',                            ec='#8B7E66'))

1 基本繪圖

R語言 – 線圖繪製

對應程式碼:

import numpy as np  import matplotlib.pyplot as plt    import example_utils    x = np.linspace(0, 10, 100)    fig, axes = example_utils.setup_axes()  for ax in axes:      ax.margins(y=0.10)    # 子圖1 默認plot多條線,顏色系統分配  for i in range(1, 6):      axes[0].plot(x, i * x)    # 子圖2 展示線的不同linestyle  for i, ls in enumerate(['-', '--', ':', '-.']):      axes[1].plot(x, np.cos(x) + i, linestyle=ls)    # 子圖3 展示線的不同linestyle和marker  for i, (ls, mk) in enumerate(zip(['', '-', ':'], ['o', '^', 's'])):      axes[2].plot(x, np.cos(x) + i * x, linestyle=ls, marker=mk, markevery=10)    # 設置標題  # example_utils.title(fig, '"ax.plot(x, y, ...)": Lines and/or markers', y=0.95)  # 保存圖片  fig.savefig('plot_example.png', facecolor='none')  # 展示圖片  plt.show()

2 散點圖

R語言 – 箱線圖(小提琴圖、抖動圖、區域散點圖)

對應程式碼:

"""  散點圖的基本用法  """  import numpy as np  import matplotlib.pyplot as plt    import example_utils    # 隨機生成數據  np.random.seed(1874)  x, y, z = np.random.normal(0, 1, (3, 100))  t = np.arctan2(y, x)  size = 50 * np.cos(2 * t)**2 + 10    fig, axes = example_utils.setup_axes()    # 子圖1  axes[0].scatter(x, y, marker='o',  color='darkblue', facecolor='white', s=80)  example_utils.label(axes[0], 'scatter(x, y)')    # 子圖2  axes[1].scatter(x, y, marker='s', color='darkblue', s=size)  example_utils.label(axes[1], 'scatter(x, y, s)')    # 子圖3  axes[2].scatter(x, y, s=size, c=z,  cmap='gist_ncar')  example_utils.label(axes[2], 'scatter(x, y, s, c)')    # example_utils.title(fig, '"ax.scatter(...)": Colored/scaled markers',  #                     y=0.95)  fig.savefig('scatter_example.png', facecolor='none')    plt.show()

3 柱狀圖

R語言 – 柱狀圖

對應程式碼:

import numpy as np  import matplotlib.pyplot as plt    import example_utils      def main():      fig, axes = example_utils.setup_axes()        basic_bar(axes[0])      tornado(axes[1])      general(axes[2])        # example_utils.title(fig, '"ax.bar(...)": Plot rectangles')      fig.savefig('bar_example.png', facecolor='none')      plt.show()    # 子圖1  def basic_bar(ax):      y = [1, 3, 4, 5.5, 3, 2]      err = [0.2, 1, 2.5, 1, 1, 0.5]      x = np.arange(len(y))      ax.bar(x, y, yerr=err, color='lightblue', ecolor='black')      ax.margins(0.05)      ax.set_ylim(bottom=0)      example_utils.label(ax, 'bar(x, y, yerr=e)')    # 子圖2  def tornado(ax):      y = np.arange(8)      x1 = y + np.random.random(8) + 1      x2 = y + 3 * np.random.random(8) + 1      ax.barh(y, x1, color='lightblue')      ax.barh(y, -x2, color='salmon')      ax.margins(0.15)      example_utils.label(ax, 'barh(x, y)')    # 子圖3  def general(ax):      num = 10      left = np.random.randint(0, 10, num)      bottom = np.random.randint(0, 10, num)      width = np.random.random(num) + 0.5      height = np.random.random(num) + 0.5      ax.bar(left, height, width, bottom, color='salmon')      ax.margins(0.15)      example_utils.label(ax, 'bar(l, h, w, b)')      main()

4 填充畫圖

對應程式碼:

"""  fill函數的各種用法  """  import numpy as np  import matplotlib.pyplot as plt    import example_utils      # -- 產生數據 ----------------------      def stackplot_data():      x = np.linspace(0, 10, 100)      y = np.random.normal(0, 1, (5, 100))      y = y.cumsum(axis=1)      y -= y.min(axis=0, keepdims=True)      return x, y      def sin_data():      x = np.linspace(0, 10, 100)      y = np.sin(x)      y2 = np.cos(x)      return x, y, y2      def fill_data():      t = np.linspace(0, 2*np.pi, 100)      r = np.random.normal(0, 1, 100).cumsum()      r -= r.min()      return r * np.cos(t), r * np.sin(t)      def fill_example(ax):      # fill一個多邊形區域      x, y = fill_data()      ax.fill(x, y, color='lightblue')      ax.margins(0.1)      example_utils.label(ax, 'fill')      def fill_between_example(ax):      # 兩條線間填充      x, y1, y2 = sin_data()        # fill_between的最常用法1      err = np.random.rand(x.size)**2 + 0.1      y = 0.7 * x + 2      ax.fill_between(x, y + err, y - err, color='orange')        # 最常用法2:兩條曲線相交區域對應不同填充色      ax.fill_between(x, y1, y2, where=y1 > y2, color='lightblue')      ax.fill_between(x, y1, y2, where=y1 < y2, color='forestgreen')        # 最常用法3      ax.fill_betweenx(x, -y1, where=y1 > 0, color='red', alpha=0.5)      ax.fill_betweenx(x, -y1, where=y1 < 0, color='blue', alpha=0.5)        ax.margins(0.15)      example_utils.label(ax, 'fill_between/x')      def stackplot_example(ax):      # Stackplot就是多次調用 ax.fill_between      x, y = stackplot_data()      ax.stackplot(x, y.cumsum(axis=0), alpha=0.5)      example_utils.label(ax, 'stackplot')      def main():      fig, axes = example_utils.setup_axes()        fill_example(axes[0])      fill_between_example(axes[1])      stackplot_example(axes[2])        # example_utils.title(fig, 'fill/fill_between/stackplot: Filled polygons',      #                     y=0.95)      fig.savefig('fill_example.png', facecolor='none')      plt.show()      main()

5 imshow

一個震撼的交互型3D可視化R包 – 可直接轉ggplot2圖為3D

對應程式碼:

import matplotlib.pyplot as plt  import numpy as np  from matplotlib.cbook import get_sample_data  from mpl_toolkits import axes_grid1    import example_utils      def main():      fig, axes = setup_axes()      plot(axes, *load_data())      # example_utils.title(fig, '"ax.imshow(data, ...)": Colormapped or RGB arrays')      fig.savefig('imshow_example.png', facecolor='none')      plt.show()      def plot(axes, img_data, scalar_data, ny):        # 默認線性插值      axes[0].imshow(scalar_data, cmap='gist_earth', extent=[0, ny, ny, 0])        # 最近鄰插值      axes[1].imshow(scalar_data, cmap='gist_earth', interpolation='nearest',                     extent=[0, ny, ny, 0])        # 展示RGB/RGBA數據      axes[2].imshow(img_data)      def load_data():      img_data = plt.imread(get_sample_data('5.png'))      ny, nx, nbands = img_data.shape      scalar_data = np.load(get_sample_data('bivariate_normal.npy'))      return img_data, scalar_data, ny      def setup_axes():      fig = plt.figure(figsize=(6, 3))      axes = axes_grid1.ImageGrid(fig, [0, 0, .93, 1], (1, 3), axes_pad=0)        for ax in axes:          ax.set(xticks=[], yticks=[])      return fig, axes      main()

6 pcolor

還在用PCA降維?快學學大牛最愛的t-SNE演算法吧, 附Python/R程式碼

對應程式碼:

"""  pcolor/pcolormesh的基本用法  記住一點:假如數據在矩形區域內建議使用imshow,這樣速度更快。此例子展示imshow不能使用的場景    """  import matplotlib.pyplot as plt  import numpy as np  from matplotlib.cbook import get_sample_data    import example_utils    # 拿到數據 ...  z = np.load(get_sample_data('./bivariate_normal.npy'))  ny, nx = z.shape  y, x = np.mgrid[:ny, :nx]  y = (y - y.mean()) * (x + 10)**2    mask = (z > -0.1) & (z < 0.1)  z2 = np.ma.masked_where(mask, z)    fig, axes = example_utils.setup_axes()    # pcolor 或 pcolormesh 都可,後者效率更高  axes[0].pcolor(x, y, z, cmap='gist_earth')  example_utils.label(axes[0], 'either')    # pcolor和pcolormesh的不同展示  # 使用pcolor  axes[1].pcolor(x, y, z2, cmap='gist_earth', edgecolor='black')  example_utils.label(axes[1], 'pcolor(x,y,z)')    # 使用pcolormesh  axes[2].pcolormesh(x, y, z2, cmap='gist_earth', edgecolor='black', lw=0.5,                     antialiased=True)  example_utils.label(axes[2], 'pcolormesh(x,y,z)')    #example_utils.title(fig, 'pcolor/pcolormesh: Colormapped 2D arrays')  fig.savefig('pcolor_example.png', facecolor='none')    plt.show()

7 contour

對應程式碼:

import matplotlib.pyplot as plt  import numpy as np  from matplotlib.cbook import get_sample_data    import example_utils    z = np.load(get_sample_data('bivariate_normal.npy'))    fig, axes = example_utils.setup_axes()    axes[0].contour(z, cmap='gist_earth')  example_utils.label(axes[0], 'contour')    axes[1].contourf(z, cmap='gist_earth')  example_utils.label(axes[1], 'contourf')    axes[2].contourf(z, cmap='gist_earth')  cont = axes[2].contour(z, colors='black')  axes[2].clabel(cont, fontsize=6)  example_utils.label(axes[2], 'contourf + contourn + clabel')    # example_utils.title(fig, '"contour, contourf, clabel": Contour/label 2D data',  #                     y=0.96)  fig.savefig('contour_example.png', facecolor='none')    plt.show()

8 向量場

對應程式碼:

import matplotlib.pyplot as plt  import numpy as np    import example_utils    # Generate data  n = 256  x = np.linspace(-3, 3, n)  y = np.linspace(-3, 3, n)  xi, yi = np.meshgrid(x, y)  z = (1 - xi / 2 + xi**5 + yi**3) * np.exp(-xi**2 - yi**2)  dy, dx = np.gradient(z)  mag = np.hypot(dx, dy)    fig, axes = example_utils.setup_axes()    # 單箭頭  axes[0].arrow(0, 0, -0.5, 0.5, width=0.005, color='black')  axes[0].axis([-1, 1, -1, 1])  example_utils.label(axes[0], 'arrow(x, y, dx, dy)')    # ax.quiver  ds = np.s_[::16, ::16]  # Downsample our array a bit...  axes[1].quiver(xi[ds], yi[ds], dx[ds], dy[ds], z[ds], cmap='gist_earth',                 width=0.01, scale=0.25, pivot='middle')  axes[1].axis('tight')  example_utils.label(axes[1], 'quiver(x, y, dx, dy)')    # ax.streamplot  # 寬度和顏色變化  lw = 2 * (mag - mag.min()) / mag.ptp() + 0.2  axes[2].streamplot(xi, yi, dx, dy, color=z, density=1.5, linewidth=lw,                     cmap='gist_earth')  example_utils.label(axes[2], 'streamplot(x, y, dx, dy)')    # example_utils.title(fig, '"arrow/quiver/streamplot": Vector fields', y=0.96)  # fig.savefig('vector_example.png', facecolor='none')    plt.show()

9 數據分布圖

R語言 – 箱線圖一步法

對應程式碼:

"""  Matplotlib 提供許多專業的繪製統計學相關的圖函數    更多統計學相關圖可使用 Seaborn 庫,它基於Matplotlib編寫。  """  import numpy as np  import matplotlib.pyplot as plt    import example_utils      def main():      colors = ['cyan', 'red', 'blue', 'green', 'purple']      dists = generate_data()        fig, axes = example_utils.setup_axes()      hist(axes[0], dists, colors)      boxplot(axes[1], dists, colors)      violinplot(axes[2], dists, colors)        # example_utils.title(fig, 'hist/boxplot/violinplot: Statistical plotting',      #                     y=0.9)      fig.savefig('statistical_example.png', facecolor='none')        plt.show()      def generate_data():      means = [0, -1, 2.5, 4.3, -3.6]      sigmas = [1.2, 5, 3, 1.5, 2]      # 每一個分布的樣本個數      nums = [150, 1000, 100, 200, 500]        dists = [np.random.normal(*args) for args in zip(means, sigmas, nums)]      return dists    # 頻率分布直方圖  def hist(ax, dists, colors):      ax.set_color_cycle(colors)      for dist in dists:          ax.hist(dist, bins=20, density=True, edgecolor='none', alpha=0.5)        ax.margins(y=0.05)      ax.set_ylim(bottom=0)        example_utils.label(ax, 'ax.hist(dists)')    # 箱型圖  def boxplot(ax, dists, colors):      result = ax.boxplot(dists, patch_artist=True, notch=True, vert=False)        for box, color in zip(result['boxes'], colors):          box.set(facecolor=color, alpha=0.5)      for item in ['whiskers', 'caps', 'medians']:          plt.setp(result[item], color='gray', linewidth=1.5)      plt.setp(result['fliers'], markeredgecolor='gray', markeredgewidth=1.5)      plt.setp(result['medians'], color='black')        ax.margins(0.05)      ax.set(yticks=[], ylim=[0, 6])        example_utils.label(ax, 'ax.boxplot(dists)')    #小提琴圖  def violinplot(ax, dists, colors):      result = ax.violinplot(dists, vert=False, showmedians=True)      for body, color in zip(result['bodies'], colors):          body.set(facecolor=color, alpha=0.5)      for item in ['cbars', 'cmaxes', 'cmins', 'cmedians']:          plt.setp(result[item], edgecolor='gray', linewidth=1.5)      plt.setp(result['cmedians'], edgecolor='black')        ax.margins(0.05)      ax.set(ylim=[0, 6])        example_utils.label(ax, 'ax.violinplot(dists)')      main()

本文參考:

https://nbviewer.jupyter.org/github/matplotlib/AnatomyOfMatplotlib/blob/master/AnatomyOfMatplotlib-Part2-Plotting_Methods_Overview.ipynb