Hi, I am trying to plot a hexbin plot, which would act as a heatmap, and want to update it every few seconds with new data. Right now I have this, serving as an MRE:
import numpy as np
from bokeh.models import HoverTool, ColumnDataSource
from bokeh.plotting import figure, curdoc
from bokeh.models import ColumnDataSource
n = 500
x = np.random.normal(size = n)
y = np.random.normal(size = n)
source = ColumnDataSource(dict(x = x, y = y))
p = figure(title="Hexbin for 500 points", match_aspect=True,
tools="wheel_zoom,reset,pan", background_fill_color='#440154')
p.grid.visible = False
r, _ = p.hexbin(x, y, size=0.1, hover_color="pink", hover_alpha=0.8)
p.add_tools(HoverTool(
tooltips=[("count", "@c"), ("(q,r)", "(@q, @r)")],
mode="mouse", point_policy="follow_mouse", renderers=[r],
))
def update():
global x, y, p, r
p.renderers.remove(r)
x = np.random.normal(size = n)
y = np.random.normal(size = n)
r, _ = p.hexbin(x, y, size=0.1, hover_color="pink", hover_alpha=0.8)
curdoc().add_periodic_callback(update, 1000)
curdoc().add_root(p)
This does the well for this sized data, however, for my data, the “blinking” which happens everytime the update function is called through the periodic callback is undesirable. Furthermore, it also plots the hexbins over any existing glyphs that are already on my plot which is also undesirable. As such, I was wondering if there was any way to stream data to a ColumnDataSource, as one would do with a scatter plot, and have that act as my stream instead. The code below shows what I would like to be able to do:
import numpy as np
from bokeh.models import HoverTool, ColumnDataSource
from bokeh.plotting import figure, curdoc
from bokeh.models import ColumnDataSource
n = 500
x = np.random.normal(size = n)
y = np.random.normal(size = n)
source = ColumnDataSource(dict(x = [], y = []))
p = figure(title="Hexbin for 500 points", match_aspect=True,
tools="wheel_zoom,reset,pan", background_fill_color='#440154')
p.grid.visible = False
r, _ = p.hexbin("x", "y", size=0.1, hover_color="pink", hover_alpha=0.8, source = source)
p.add_tools(HoverTool(
tooltips=[("count", "@c"), ("(q,r)", "(@q, @r)")],
mode="mouse", point_policy="follow_mouse", renderers=[r],
))
def update():
global x, y, p, r
p.renderers.remove(r)
x = np.random.normal(size = n)
y = np.random.normal(size = n)
source.stream(dict(x=x, y=y))
curdoc().add_periodic_callback(update, 1000)
curdoc().add_root(p)
I do realize that this may be a futile question as the docs indicate that the hexbin
function does not take a ColumnDataSource as an argument but I was wondering if anyone had any ideas on a workaround for this?
Thanks