class PlotImage(QwtPlotItem): def __init__(self, title=QwtText()): QwtPlotItem.__init__(self) self.setTitle(title) self.setItemAttribute(QwtPlotItem.Legend) self.xyzs = None def setData(self, xyzs, xRange=None, yRange=None): self.xyzs = xyzs shape = xyzs.shape if not xRange: xRange = (0, shape[0]) if not yRange: yRange = (0, shape[1]) self.xMap = QwtScaleMap(0, xyzs.shape[0], *xRange) self.plot().setAxisScale(QwtPlot.xBottom, *xRange) self.yMap = QwtScaleMap(0, xyzs.shape[1], *yRange) self.plot().setAxisScale(QwtPlot.yLeft, *yRange) self.image = toQImage(bytescale(self.xyzs)).mirrored(False, True) for i in range(0, 256): self.image.setColor(i, qRgb(i, 0, 255 - i)) def updateLegend(self, legend): QwtPlotItem.updateLegend(self, legend) legend.find(self).setText(self.title()) def draw(self, painter, xMap, yMap, rect): """Paint image zoomed to xMap, yMap Calculate (x1, y1, x2, y2) so that it contains at least 1 pixel, and copy the visible region to scale it to the canvas. """ assert (isinstance(self.plot(), QwtPlot)) # calculate y1, y2 # the scanline order (index y) is inverted with respect to the y-axis y1 = y2 = self.image.height() y1 *= (self.yMap.s2() - yMap.s2()) y1 /= (self.yMap.s2() - self.yMap.s1()) y1 = max(0, int(y1 - 0.5)) y2 *= (self.yMap.s2() - yMap.s1()) y2 /= (self.yMap.s2() - self.yMap.s1()) y2 = min(self.image.height(), int(y2 + 0.5)) # calculate x1, x2 -- the pixel order (index x) is normal x1 = x2 = self.image.width() x1 *= (xMap.s1() - self.xMap.s1()) x1 /= (self.xMap.s2() - self.xMap.s1()) x1 = max(0, int(x1 - 0.5)) x2 *= (xMap.s2() - self.xMap.s1()) x2 /= (self.xMap.s2() - self.xMap.s1()) x2 = min(self.image.width(), int(x2 + 0.5)) # copy image = self.image.copy(x1, y1, x2 - x1, y2 - y1) # zoom image = image.scaled(xMap.p2() - xMap.p1() + 1, yMap.p1() - yMap.p2() + 1) # draw painter.drawImage(xMap.p1(), yMap.p2(), image)
class PlotImage(QwtPlotItem): def __init__(self, title = QwtText()): QwtPlotItem.__init__(self) self.setTitle(title) self.setItemAttribute(QwtPlotItem.Legend); self.xyzs = None def setData(self, xyzs, xRange = None, yRange = None): self.xyzs = xyzs shape = xyzs.shape if not xRange: xRange = (0, shape[0]) if not yRange: yRange = (0, shape[1]) self.xMap = QwtScaleMap(0, xyzs.shape[0], *xRange) self.plot().setAxisScale(QwtPlot.xBottom, *xRange) self.yMap = QwtScaleMap(0, xyzs.shape[1], *yRange) self.plot().setAxisScale(QwtPlot.yLeft, *yRange) self.image = toQImage(bytescale(self.xyzs)).mirrored(False, True) for i in range(0, 256): self.image.setColor(i, qRgb(i, 0, 255-i)) def updateLegend(self, legend): QwtPlotItem.updateLegend(self, legend) legend.find(self).setText(self.title()) def draw(self, painter, xMap, yMap, rect): """Paint image zoomed to xMap, yMap Calculate (x1, y1, x2, y2) so that it contains at least 1 pixel, and copy the visible region to scale it to the canvas. """ assert(isinstance(self.plot(), QwtPlot)) # calculate y1, y2 # the scanline order (index y) is inverted with respect to the y-axis y1 = y2 = self.image.height() y1 *= (self.yMap.s2() - yMap.s2()) y1 /= (self.yMap.s2() - self.yMap.s1()) y1 = max(0, int(y1-0.5)) y2 *= (self.yMap.s2() - yMap.s1()) y2 /= (self.yMap.s2() - self.yMap.s1()) y2 = min(self.image.height(), int(y2+0.5)) # calculate x1, x2 -- the pixel order (index x) is normal x1 = x2 = self.image.width() x1 *= (xMap.s1() - self.xMap.s1()) x1 /= (self.xMap.s2() - self.xMap.s1()) x1 = max(0, int(x1-0.5)) x2 *= (xMap.s2() - self.xMap.s1()) x2 /= (self.xMap.s2() - self.xMap.s1()) x2 = min(self.image.width(), int(x2+0.5)) # copy image = self.image.copy(x1, y1, x2-x1, y2-y1) # zoom image = image.scaled(xMap.p2()-xMap.p1()+1, yMap.p1()-yMap.p2()+1) # draw painter.drawImage(xMap.p1(), yMap.p2(), image)