Hi, there have been attempts to change the colormap and other attributes of a plot.
The solution in this forum so far has been to create a new plot object with the new cmap.
However, sometimes this is not desired or feasible (large plots or keeping existing zoom level).
So, I pieced together a small example of how jslink can be used to update a heatmap’s colorbar range and colormap via JS, instead of re-creating the plot from scratch every time.
Result:
Code:
cmaps = matplotlib.pyplot.colormaps()
cmap_dict = {}
for cmap in cmaps:
_cmap = matplotlib.cm.get_cmap(str(cmap), 12)
cmap_dict[str(cmap)] = [matplotlib.colors.rgb2hex(_cmap(i)[:3]) for i in range(_cmap.N)]
def get_blank_plot():
#p1 = hv.Curve([],kdims=["Date"],vdims=["Price [BTC]"]).opts(responsive=True)
ls = np.linspace(0, 10, 200)
xx, yy = np.meshgrid(ls, ls)
p1 = hv.Image(np.sin(xx)*np.cos(yy),kdims=['x','y'],vdims=['z']).opts(responsive=False,cmap='viridis',colorbar=True,colorbar_position='left',yaxis='right',colorbar_opts={'title':'z.'},xaxis=None,show_grid=True)
return p1
class Example(param.Parameterized):
EXAMPLE_PLOT = get_blank_plot().opts(width=500,height=400)
def __init__(self, **params):
super().__init__(**params)
self.plot_pane = pn.pane.HoloViews(self.EXAMPLE_PLOT)
self.cmap = pn.widgets.Select(options=list(cmap_dict.keys()))
self.colormap_slider = pn.widgets.RangeSlider(end=1,start=0,step=0.1,name='Colorbar Slider')
# Change colorbar range
self.colormap_slider.jslink(self.plot_pane, code={'value':'''
color_mapper.low = source.value[0];
color_mapper.high = source.value[1];
'''})
# Change cmap
self.cmap.jslink(self.plot_pane, code={'value':'''
console.log('Cmap is', source.value)
color_mapper.palette = colors[source.value];
'''},args={'colors': cmap_dict})
def panel(self):
return pn.Column(pn.Row(self.colormap_slider,self.cmap),self.plot_pane)
app = Example(name='')
app.panel()
Essentially, you access bokeh’s glyph object via the jslink to change some properties of an already existing plot. It took me some time to figure out which glyph parameters corresponded to which plot properties and how to change them. I imagine others have been struggling with that too. So, I thought I’d share.
The resources on Panel’s documentation, as well as @jsignell’s PyData talk helped a lot!
Unfortunately, it requires writing a bit of JS, which I have no experience with.
Also, the palette currently only takes an array of str colors or hex colors. Would be nice to just pass the colormap str directly (i.e. ‘viridis’).