导出为ndarray格式图片
matplotlib
绘制的图线有自己的显示窗口,有时候希望在其他的UI设计中使用其绘制的图,比如PyQt,官方有一个支持QT的显示窗口类,但配置很麻烦,在这里记录一种简便的导出方式
主要思路为使用matplotlib的print_png
函数将其图片数据导出到二进制流中,然后numpy从此二进制流中取出数据即可
代码如下:
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
| import matplotlib.pyplot as plt import numpy as np import io import cv2
x = [1, 2, 3, 4] y = [1.2, 2.5, 4.5, 7.3]
fig = plt.figure("Image", frameon=False) plt.plot(x,y) canvas = fig.canvas
buffer = io.BytesIO() canvas.print_png(buffer) data = buffer.getvalue() buffer.write(data) buffer.seek(0)
file_bytes = np.asarray(bytearray(buffer.read()), dtype=np.uint8)
img = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
buffer.close()
|
设置matplotlib
borders便于鼠标信息处理(坐标)
有时候仅导出为图片还不够,还需要实现用户的交互操作,在原生matplotlib中可以绑定事件以实现用户交互,但导出为图片时,就不得行了,但只需要获取坐标和图片宽高之间的关系,就可以简单的坐标转换一下就可以实现了
1 2 3
| left, bottom, right, top = 0.1, 0.1, 0.9, 0,9 plt.subplots_adjust(left=left, bottom=bottom, right=right, top=top)
|
坐标转换
因为知道绘图区在整个图的相对位置,所以可以很好的处理
下面例子为PyQt5使用widget显示图片,widget到曲线坐标系的转换(曲线坐标系x,y均在[0,1]之间)
即左上角为原点的屏幕坐标系到[0,1]坐标范围的图表坐标系的转换
1 2 3 4 5 6
| w, h = width(), height() plot_w, plot_h = (right - left)*w, (top - bottom)*h
coord2bk = lambda coord: [coord[0]*plot_w + w*left, h*(1-bottom) - coord[1]*plot_h]
bk2coord = lambda coord: [(coord[0] - w*left) / plot_w ,1 - (coord[1] - h*(1-top)) / plot_h]
|