Log color scale in imageview

695 views
Skip to first unread message

Eric Evarts

unread,
Dec 19, 2013, 10:59:34 AM12/19/13
to pyqt...@googlegroups.com
Hello,
I am trying to do logarithmic color mapping.  I am using an imageView widget for displaying my data, but I cannot seem to figure out how to set the color scaling to be log instead of linear.  Is this possible?

Thanks,
Eric

Luke Campagnola

unread,
Dec 19, 2013, 12:59:30 PM12/19/13
to pyqt...@googlegroups.com
On Thu, Dec 19, 2013 at 10:59 AM, Eric Evarts <erev...@gmail.com> wrote:
I am trying to do logarithmic color mapping.  I am using an imageView widget for displaying my data, but I cannot seem to figure out how to set the color scaling to be log instead of linear.  Is this possible?

The easiest thing to do is just transform the data before displaying it like `pg.image(np.log(data))`.
If you really want the color mapping itself to be logarithmic, then we can discuss other options..
 

Eric Evarts

unread,
Jan 2, 2014, 12:55:35 PM1/2/14
to pyqt...@googlegroups.com
Hi Luke,

Taking the log of the data first worked just fine (although I did need to do a little extra data massaging because I have some data that went negative due to a background subtraction).  It would be nice if I could keep the histogram values as the original data values instead of the log values, but that is not a big deal.

Thanks!

Luke Campagnola

unread,
Jan 4, 2014, 12:37:19 AM1/4/14
to pyqt...@googlegroups.com
On Thu, Jan 2, 2014 at 12:55 PM, Eric Evarts <erev...@gmail.com> wrote:
Hi Luke,

Taking the log of the data first worked just fine (although I did need to do a little extra data massaging because I have some data that went negative due to a background subtraction).  It would be nice if I could keep the histogram values as the original data values instead of the log values, but that is not a big deal.

Another possibility is to construct a logarithmic colormap:

import pyqtgraph as pg
import numpy as np

img = np.exp(np.random.normal(size=(100,100), scale=1.0))

v = pg.image(img)

# approximate log lookup table as a set of 10 log-spaced linear transitions
pos = np.exp(np.linspace(-5, 0, 10))
color = np.empty((10,4), dtype=np.ubyte)
color[:,:3] = np.linspace(0, 255, 10).reshape(10, 1)
color[:,3] = 255
cm = pg.ColorMap(pos, color)

v.ui.histogram.gradient.setColorMap(cm)

The limitation to this approach is that if your data spans a much larger logarithmic range, then the automatically generated 512-value lookup table will not be sufficient to display the data (and the necessary lookup table size would grow exponentially with the log-range of the data). For example, I can create a 4 MB lookup table to cover a much larger range:

# image with larger log-range
img = np.exp(np.random.normal(size=(100,100), scale=3.0))

v = pg.image(img)

# manually construct a larger lookup table to handle this data
N = 1000000
lut = np.empty((N,4), dtype=np.ubyte)
grad = np.log(np.linspace(1, 1e5, N))
lut[:,:3] = (255 * grad / grad.max()).reshape(N,1)
lut[:, 3] = 255
v.imageItem.setLookupTable(lut)
# note that the LUT is reset if you modify the gradient in the imageview.

For anything larger than that, I think it would be necessary to use a different method than lookup tables. ColorMap already uses scipy.interpolate.griddata to accomplish this, but ImageItem is currently not built to handle that (although it would only require minor changes to get there).


Luke


 




 
Reply all
Reply to author
Forward
0 new messages