在wx中使用matplotlib显示numpy数组
我有一个很大的numpy数组,形状是(M x N x 3),数据类型是float32
。我想把这个图像显示在一个wx.Frame
窗口里,并且这个窗口里有一个wx.ScrolledWindow
。我希望图像能以100%的大小显示,而且非常重要的是,不能有数据丢失。这些是超高分辨率的X光图像,必须保持浮点值。
到目前为止,wx.Image
的功能不太行,因为它只接受8位整数的数组,这样不够用。
PIL图像库也只能处理8位的,显然不够。
目前我找到的唯一合适的库是matplotlib,但我在让matplotlib按我想要的方式显示时遇到了麻烦。这段代码让我接近目标:
class View(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,
parent=None,
title="DICOM Viewer",
size=(1280, 750),
pos=(0,0))
self.scroll = wx.ScrolledWindow(self, -1)
self.figure = plt.Figure()
self.canvas = FigureCanvasWxAgg(self.scroll, -1, self.figure)
self.axes = Axes(self.figure, [0,1,0,1])
self.figure.figimage(ndarray)
self.sizer.Add(self.canvas, 1, wx.EXPAND)
self.scroll.SetSizer(self.sizer)
figimage函数只会显示原始像素,这正是我想要的,但它只填充wxFrame可视区域,而且速度非常慢。可能是我的wx控件有问题?
一个更好的解决方案是使用imshow,如下所示:
class View(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,
parent=None,
title="DICOM Viewer",
size=(1280, 750),
pos=(0,0))
self.scroll = wx.ScrolledWindow(self, -1)
self.figure = plt.Figure()
self.canvas = FigureCanvasWxAgg(self.scroll, -1, self.figure)
self.axes = Axes(self.figure, [0,1,0,1])
self.axes = self.figure.add_subplot(111)
self.axes.imshow(ndarray)
self.sizer.Add(self.canvas, 1, wx.EXPAND)
self.scroll.SetSizer(self.sizer)
不过,这样做会在图表周围留出很多空白,还会出现不必要的坐标轴和标签,并且会自动缩放图像以适应可视区域。虽然像素质量还是有的,但需要添加mpl工具栏,还要手动平移,如果平移得太远,可能会失去对图像的控制。
1 个回答
1
我找到了解决办法:
class View(wx.Frame): def __init__(self): wx.Frame.__init__(self, parent=None, title="DICOM Viewer", size=(1280, 750), pos=(0,0)) self.scroll = wx.ScrolledWindow(self, -1) h, w, r = ndarray.shape self.figure = plt.Figure((w/72.0,h/72.0), 72) #manually determine the figure size in inches self.canvas = FigureCanvasWxAgg(self.scroll, -1, self.figure) self.axes = self.figure.add_axes([0.0, 0.0, 1.0, 1.0]) #size of axes to match size of figure self.axes.imshow(ndarray)
关键是手动设置图形的大小,让它和图片的实际大小一致(以英寸为单位),然后把图形的坐标轴也设置成一样的大小。这样就能防止mpl自动调整我的图片大小,以适应可视区域。我还去掉了调整器,因为我手动设置了滚动条的虚拟区域、图形和坐标轴的大小。现在如果能把图形顶部的边距去掉就完美了。