Accelerating with WebGL

Bokeh provides limited support for WebGL to render plots in a web browser. Using WebGL in Bokeh can be useful when visualizing larger data sets, for example.

WebGL is a JavaScript API that allows rendering content in the browser using hardware acceleration from a Graphics Processing Unit (GPU). WebGL is standardized and available in all modern browsers.

If you use Bokeh’s WebGL output backend, Bokeh will automatically detect if the browser supports WebGL. When you use WebGL-enabled elements in your Bokeh plot but the browser doesn’t support WebGL, Bokeh will automatically use the default canvas renderer instead.

Enabling WebGL

To enable WebGL in Bokeh, set the plot’s output_backend property to "webgl":

p = figure(output_backend="webgl")

The WebGL output backend only supports a subset of Bokeh’s glyphs. When you enable WebGL, you are requesting that WebGL rendering is used if available. Glyphs that are not available in the WebGL output backend are rendered with the default canvas backend.

Supported glyphs

Bokeh’s WebGL support covers the following fixed-shape glyphs:

WebGL support for these fixed-shape glyphs covers the following properties:

There is also full WebGL support for line() glyphs, although the appearance of dashed lines with round and square end caps may differ slightly from the default HTML canvas rendering.

If you enable Bokeh’s webGL output backend, WebGL will be used whenever supported by a browser. This includes output in Jupyter notebooks or Jupyter lab and when exporting Bokeh plots to PNG if the underlying browser (including headless browsers) supports WebGL. In case a browser does not support WebGL, Bokeh automatically falls back to the standard canvas output backend.

When to use WebGL

A general rule of thumb is that Bokeh’s default canvas output backend works well if you are rendering fewer than 10,000 markers or points. For plots with more than 25,000 markers or points, WebGL will usually give noticeably better performance. Generally, the more markers or points to render, the more efficient WebGL will be compared to the default canvas output backend. The number of markers or points at which WebGL performance exceeds canvas depends on the hardware available, so you will need to try it out on your own hardware to see what is best for you.

WebGL examples

The following example is a plot with 10,000 scatter circles with WebGL enabled. Notice that the plot can be panned and zoomed smoothly, even without downsampling the data.

import numpy as np

from bokeh.plotting import figure, output_file, show

output_file("scatter10k.html", title="scatter 10k points")

N = 10000

x = np.random.normal(0, np.pi, N)
y = np.sin(x) + np.random.normal(0, 0.2, N)

TOOLS = "pan,wheel_zoom,box_zoom,reset,save,box_select"

p = figure(tools=TOOLS, output_backend="webgl")
p.circle(x, y, alpha=0.1, nonselection_alpha=0.001)

show(p)

Similarly, the plot below demonstrates plotting a single line with 10,000 points.

import numpy as np

from bokeh.plotting import figure, output_file, show

output_file("line10k.html", title="line10k.py example")

N = 10000
x = np.linspace(0, 10*np.pi, N)
y = np.cos(x) + np.sin(2*x+1.25) + np.random.normal(0, 0.001, (N, ))

p = figure(title="A line consisting of 10k points", output_backend="webgl")
p.line(x, y, color="#22aa22", line_width=3)

show(p)