Hi,
Luke: I have issues with my current use of this code. It works, but only if
Qt, PySide and pyqtgraph are installed in the correct order. Otherwise, the
window is frozen and doesn't update. I have no clue where the bug lies. I'm
also using somewhat outdated versions of the libraries (the app is written
in python 2.7...).
Patrick: the output of pcolormesh has a method to convert it to a raster.
This helps when saving large datasets to vectorial formats.
import numpy as np
import matplotlib.pyplot as plt
irreg_xlabels = np.array([0,1,3,7])
irreg_ylabels = np.array([0,2,5,9])
irreg_data = np.outer(irreg_xlabels, irreg_ylabels)
plt.pcolormesh(irreg_xlabels, irreg_ylabels, irreg_data).set_rasterized(True
)
plt.savefig("rasterized.pdf")
On Thursday, 16 August 2018 04:56:07 UTC+2, Patrick wrote:
>
> Hi,
>
> Funnily enough I was looking for a pcolormesh equivalent in pyqtgraph just
> the other day, and searching didn't come up with much except this old
> thread (which is not a suitable solution for me -- my pixel sizes are
> dramatically different sizes).
>
> The way matplotlib does the pcolormesh is by creating a large number of
> rectangular patches, each rectangle is the width/height of the pixel size,
> with a face color mapped to the z value. The hundreds (thousands?!) of
> patches are then placed on the plot axes. You can see this when exporting
> to a vector graphic (SVG, PDF) versus a raster (PNG) -- the vector graphic
> is larger file size and horribly slow to render!
>
> The quick and dirty workaround for this is to simply interpolate the
> irregularly spaced data onto a regular grid. I was going to try this first,
> as it's pretty easy. The issue is that with drastically different sized
> pixels, we need to choose an interpolation grid size. If we choose the
> smallest increment, then the resulting image may be enormous (large memory
> usage, possibly slow to pan/render). If we choose a larger pixel size, then
> we will lose detail when zooming in to the regions where the pixels were
> small.
> Anyway, if you wanted to try this, look at the 2D interpolation routines
> from scipy. Something like:
>
> import numpy as np
> from scipy import interpolate
>
> # Generate some test data on an irregular grid
> irreg_xlabels = np.array([0,1,3,7])
> irreg_ylabels = np.array([0,2,5,9])
> irreg_data = np.outer(irreg_xlabels, irreg_ylabels)
>
> # Choose the finest step size as our new pixel size
> # Will give best detail, but large image size!
> step_x = np.ediff1d(irreg_xlabels).min()
> step_y = np.ediff1d(irreg_ylabels).min()
>
> # Function to generate interpolated values from our irregular grid
> f = interpolate.RectBivariateSpline(irreg_xlabels, irreg_ylabels,
> irreg_data)
>
> # Generate new data on the regular grid
> xlabels = np.arange(irreg_xlabels[0], irreg_xlabels[-1] + step_x, step_x)
> ylabels = np.arange(irreg_ylabels[0], irreg_ylabels[-1] + step_y, step_y)
> data = f(xlabels, ylabels)
>
> then set the ImageItem data and translations/scale using the new, regular
> grid offset and step size.
>
> If memory use and performance is acceptable, then that should do it. If
> not, then it would be possible to dynamically generate the new interpolated
> image data when the range of the view changes. Then only get interpolated
> values between the view range and at a resolution that matches the viewport
> size.
>
> Patrick
>
> On Thursday, 16 August 2018 06:17:08 UTC+9:30, Luke Carroll wrote:
>>
>> Hey, I've tried replicating the suggestions but cant seem to get anything
>> to appear, I wrote the script below and ran it from the windows command
>> prompt using Python. I'm using numpy 1.14, pyqt 5.9 and pyqtgraph 0.10.
>> When I just use the code suggested by Samuel Palato nothing gets displayed
>> either. I've also tried running this in a jupyter notebook but to no avail.
>>
>> import numpy as np
>> import pyqtgraph as pg
>> from pyqtgraph.Qt import QtGui, QtCore
>>
>>
>> class IndexedAxis(pg.AxisItem):
>> """
>> Axis where pixels are mapped using a numpy array
>> """
>> def __init__(self, orientation, mapping=None, **kw):
>> super(IndexedAxis, self).__init__(orientation, **kw)
>> self.mapping = mapping
>> self.fmt = "{:.02f}"
>>
>> def tickStrings(self, values, scale, spacing):
>> if self.mapping is None:
>> return super(IndexedAxis, self).tickStrings(values, scale,
>> spacing)
>> # count values smaller than 0
>> labels = []
>> idx = np.array(values, dtype=np.int)-1
>> left_pad = np.count_nonzero(idx < 0)
>> right_pad = np.count_nonzero(idx >= self.mapping.size)
>> idx = np.compress(np.logical_and(idx>=0, idx< self.mapping.size),
>> idx)
>> labels.extend([""]*left_pad)
>> labels.extend([self.fmt.format(v) for v in self.mapping[idx]])
>> labels.extend([""]*right_pad)
>> return labels
>>
>> app = QtGui.QApplication([])
>> mw = QtGui.QMainWindow
>> view = pg.GraphicsLayoutWidget()
>> w1 = view.addPlot()
>>
>> x_values = np.linspace(-100, 100)
>> mapped_axis = IndexedAxis('bottom', mapping=x_values)
>> plot_item = pg.PlotItem(axisItems={'bottom': mapped_axis})
>> image_item =pg.ImageItem()
>> plot_item.addItem(image_item)
>>
>> w1.addItem(plot_item)
>>
>>
>>
>>
>>
>> On Tuesday, April 19, 2016 at 6:50:05 PM UTC+1, Samuel Palato wrote:
>>>
>>> Hi,
>>>
>>> I managed to do something similar.
>>>
>>> My data has x and y axes with almost constant spacing, so I'm ok with
>>> even sized pixels on display. However, the x and y axes display custom
>>> values, looked up from the corresponding arrays. This is a bit closer to
>>> the behavior of `matplotlib.imshow` with the `extent` keyword.
>>>
>>> The trick is to subclass `AxisItem` in order to display custom tick
>>> labels. See:
>>> https://bitbucket.org/snippets/spalato/X6nL4/indexed-axis#file-IndexedAxis.py
>>> You then need to create the axis items and pass them to the PlotItem
>>> your ImageItem is going to reside in:
>>> x_values = np.linspace(-100, 100, n=51)
>>> mapped_axis = IndexedAxis('bottom', mapping=x_values)
>>> plot_item = pg.PlotItem(axisItems={'bottom': mapped_axis})
>>> image_item =pg.ImageItem()
>>> plot_item.addItem(image_item)
>>> Or something similar.
>>> To update the axis values, you need to update the axis' `mapping`
>>> attribute to the new values.
>>>
>>> So far, this works, but I get an extra set of axes in the top right
>>> corner. (which brought me here...)
>>>
>>> If constant pixels are unacceptable, you could try creating a display
>>> image using nearest interpolation, and plotting the resulting image using
>>> the technique described above.
>>>
>>> Hope this helps,
>>> Samuel Palato
>>>
>>>
>>> On Thursday, 17 March 2016 09:37:17 UTC-4, Nicola Creati wrote:
>>>>
>>>> Hello,
>>>> I'm trying to move from Matplotlib to PyQtGraph but I need something
>>>> equivalent to the Matplotlib pcolormesh/pcolor command that accepts X, Y
>>>> and C as input. *X* and *Y *specify the (*x*, *y*) coordinates of the
>>>> colored quadrilaterals and C is the array of values. Can I get the same
>>>> with PyQtGraph, please?
>>>> Thanks.
>>>>
>>>> Nicola
>>>>
>>>
--
You received this message because you are subscribed to the Google Groups
"pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/pyqtgraph/b5cff2ba-8869-4fa1-aeb7-7d60e8e2428d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.