matplotlib: render into buffer / access pixel data

PyAV の(生半可な)紹介の中でしれーっとやっちゃったんで一応独立したネタとして。

見出しの通りで、matplotlib で show()savefig() するのではなく画像をピクセルデータとして欲しい、ってハナシ。

matplotlib: render into buffer / access pixel data

要点だけ書けば、「fig.canvas.tostring_rgb()」で取れるが明示的に描画行為をする必要がある(fig.canvas.draw())、てことだけ。

PyAV の(生半可な)紹介では av.VideoFrame.from_ndarray に渡すデータ欲しさにやってる:

 1         fig, ax = plt.subplots()
 2         ax2 = plt.subplot(1, 2, 1)
 3         left = np.fromstring(rf.planes[0].to_bytes(), dtype=np.float32)
 4         ax2.plot(left)
 5         ax2.set_ylim((-0.03, 0.03))
 6         ax2 = plt.subplot(1, 2, 2)
 7         right = np.fromstring(rf.planes[1].to_bytes(), dtype=np.float32)
 8         ax2.plot(right)
 9         ax2.set_ylim((-0.03, 0.03))
10         fig.canvas.draw()
11         ncols, nrows = fig.canvas.get_width_height()
12         rgb = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8).reshape(nrows, ncols, 3)
13         plt.close(fig)
14         # ...
15         vframe = av.VideoFrame.from_ndarray(rgb, format='rgb24')

これだけ。reshapeav.VideoFrame.from_ndarray の要件に合わせてるだけ。画像的な矩形レイアウトをあてにするの、この子。