Jatentaki Jatentaki - 1 year ago 81
Python Question

Dynamic renormalize in matplotlib after set_data

I am making an interactive display of 3d data in 2d via .imshow() method. I let the user to change the mode between viewing a single 2d layer and viewing the sum along all 2d layers. This results in large changes of range of the displayed values. For this reason keeping the same color mapping all the time results in the image becoming oversaturated and unreadable. I use .set_data() method of AxesImage class for changing the displayed data and I need a way of recalculating the color mapping at the same time. The closest I got to this goal is this function:

def blit_data(self, data):
c_norm = cs.Normalize(vmin=np.nanmin(data), vmax=np.nanmax(data))
cmap = plt.get_cmap('viridis')
scalar_map = cmx.ScalarMappable(norm=c_norm, cmap=cmap)
cmapped = scalar_map.to_rgba(data)

(cmx = matplotlib.cm, cs = matplotlib.colors, plt = matplotlib.pyplot)

However this has an unwanted side effect: mousing over a pixel in the displayed image now displays [r g b] tuple as tooltip, instead of the original float64 value, which hinders exploration of this data. For this reason I am looking for another method to achieve the same effect. A follow up question will be how to communicate this renormalization to a colorbar, so it stays relevant.

Answer Source
import matplotlib.pyplot as plt
import numpy as np

fig, (ax1, ax2) = plt.subplots(1, 2)

data = np.random.rand(10, 10)

im1 = ax1.imshow(data, interpolation='none', cmap='viridis')
im2 = ax2.imshow(data, interpolation='none', cmap='viridis')
im2.set_clim(0, .5)

example output