How can I align an pyqtgraph IsocurveItem instance to empty plot axes (rather than an ImageItem)?
How can I align an pyqtgraph IsocurveItem instance to empty plot axes (rather than an ImageItem)?
The Problem
The pyqtgraph documentation for IsocurveItem helpfully suggests that contours drawn with this class can be aligned to an ImageItem
instance by isocurve.setParentItem(image)
. But if I don't want to show image data, how can I scale the contour output to properly align with the axes given X,Y data?
ImageItem
isocurve.setParentItem(image)
Example setup
Using this code sample to draw:
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
import sys
# Setup
app = QtGui.QApplication()
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
win = pg.PlotWidget()
layout = pg.GraphicsLayout()
win.setCentralItem(layout)
ax = pg.PlotItem()
layout.addItem(ax)
# Generate data
x = np.linspace(0, 6.28, 30)
y = x[:]
xx, yy = np.meshgrid(x, y)
z = np.sin(xx) + np.cos(yy)
# Add data
ax.setXRange(x.min(), x.max())
ax.setYRange(y.min(), y.max())
c = pg.IsocurveItem(data=z, level=0.5, pen='r')
# c.setParentItem(ax) # This doesn't work
ax.addItem(c)
# Finish up
win.show()
sys.exit(app.exec_())
Which outputs this:
Or, without the setXRange and setYRange part, it looks like this:
I want the drawing from the second plot to be stretched to fit on the axes of the first one.
So, I think I just need to tell IsocurveItem how to squeeze and align itself given X, Y, Z data instead of just Z. How can I do that?
P.S. The equivalent* matplotlib contour call would be contour(x, y, z, levels=[0.5], colors='r')
.
contour(x, y, z, levels=[0.5], colors='r')
*Have to deal with axis order / row-major vs. col-major; no big deal.
Failed solutions
Add an ImageItem
and scale it, then make it invisible later. Try to make the IsocurveItem
scale as well by setting its parent to the ImageItem
:
ImageItem
IsocurveItem
ImageItem
img = pg.ImageItem(z, axisOrder='row-major')
img.scale((x.max() - x.min()) / img.width(), (y.max() - y.min()) / img.height())
ax.addItem(img)
c.setParentItem(img)
The ImageItem
scales, but the IsocurveItem
doesn't come along for the ride.
ImageItem
IsocurveItem
1 Answer
1
IsocurveItem
inherited .scale()
and .translate()
methods through GraphicsObject
, of which it is a subclass. So, just add these lines to the example after defining c
:
IsocurveItem
.scale()
.translate()
GraphicsObject
c
c.translate(x.min(), y.min())
c.scale((x.max() - x.min()) / np.shape(z)[0], (y.max() - y.min()) / np.shape(z)[1])
To make the test more rigorous, I also changed x
so it doesn't start at 0:
x
x = np.linspace(10, 16.28, 30)
The output is now
It may be a little easier to visualize with an ImageItem
in the mix (also translated and scaled):
ImageItem
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Comments
Post a Comment