导出为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]
   |