转换 绘制结果成 np.ndarray

https://stackoverflow.com/questions/7821518/matplotlib-save-plot-to-numpy-array

字符串方式

  1. fig.canvas.tostring_rgb
  2. np.fromstring

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Make a random plot...
    fig = plt.figure()
    fig.add_subplot(111)
    
    # If we haven't already shown or saved the plot, then we need to
    # draw the figure first...
    fig.canvas.draw()
    
    # Now we can save it to a numpy array.
    data = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')
    data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))

ByteIO 方式

  1. fig.savefig(byteioObj, format='png', dpi=180)
  2. byteioObj.seek(0)
  3. numpy.frombuffer(byteioObj)
  4. cv2.cvtColor

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    import io
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    # plot sin wave
    fig = plt.figure()
    ax = fig.add_subplot(111)
    
    x = np.linspace(-np.pi, np.pi)
    
    ax.set_xlim(-np.pi, np.pi)
    ax.set_xlabel("x")
    ax.set_ylabel("y")
    
    
    ax.plot(x, np.sin(x), label="sin")
    
    ax.legend()
    ax.set_title("sin(x)")
    
    
    # define a function which returns an image as numpy array from figure
    def get_img_from_fig(fig, dpi=180):
    buf = io.BytesIO()
    fig.savefig(buf, format="png", dpi=dpi)
    buf.seek(0)
    img_arr = np.frombuffer(buf.getvalue(), dtype=np.uint8)
    buf.close()
    img = cv2.imdecode(img_arr, 1)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
    return img
    
    # you can get a high-resolution image as numpy array!!
    plot_img_np = get_img_from_fig(fig)

嵌套绘图

手动绘图 plt.axes(x_pos, y_pos, x_width, y_width)

  • 返回一个 axes, 手动布局

逐个简单绘制 plt.subplot(2, 3, index)

  • 返回一个 axes, 已经做好网格分布

    • plt.subplot(2, 3, 6) –> axes

统一绘图 plot.subplots(2, 3, sharex='col', sharey='row')

  • 返回一个 axes np.ndarray, 已经做好网格分布

    • axeses[i, j] 访问对应 axes

复杂布局 plt.GridSpec() 与 plt.subplot 联合使用

设置 lim 和 label (x, y)

xlim, ylim

  • 解说

    • x, y 轴的显示范围
  • plt.xlim(x_min, y_min)

xlabel, ylabel

  • 解说

    • 坐标轴上的 tick (刻度)文字内容
  • plt.label(position_list, label_str_list)

大小

图片大小

  • plt.figure(figsize=(20,20))

xlabel 大小

  • plt.xlabel('hello', fontsize=20)

气泡图大小

  • plt.scatter(x_list, y_list, s=size_list)

如何在 notebook 中,持续更新图像

参考:

特点:

  • 同一个绘图对象,内部的图像更新
  • 图的容器仍然是同一个

实例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 我的测试
%matplotlib notebook
fig, ax = plt.subplots(1, 1)
for i in range(100):
    ax.lines.clear()
    x = np.linspace(1, 20, 100)
    x = x + i/5
    y = np.sin(x)
    ax.plot(x, y)
    fig.canvas.draw()
    time.sleep(0.02)

光谱图

垂直线图

参考:

工具:

  • vlines: matplotlib.pyplot.vlines()

例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({
    'labels' : ['Hδ', 'Hy', 'HB' , 'OII', ''  , ''  , 'Ha', ''],
    'x'      : [4100, 4400,  4900, 4950 , 5050, 5800, 6700, 6750],
    'y'      : [180 , 300 ,  500 , 800  , 1000, 100 , 1000, 100]
})


fig, ax = plt.subplots(figsize=(14,7))
ax.vlines(
    x = df.x,                   # 垂直线的 x
    ymin = [0] * len(df),       # 垂直线的 ymin
    ymax = df.y,                # 垂直线的 ymax
    linewidth=2, color='k'
)