WebGL renders colors and alphas very differently than canvas in bokeh Rect glyph

I am trying to create a track with lot of rect glyps in many places with a Xaxis that is close to a billion. I want these rectangles only visible when zoomed in to the absolute position of the glyph and remain hidden in the normal view of the figure size.

I was able to do this with a lot of trial and error with line_width, line alpha & fill_alpha properties with the canvas-backed. However, my data size got bigger and I wanted to use WebGL backend to improve performance. It did improve the performance but as a side effect, those rectangles are appearing in normal view without zooming even with the same property settings. I tried adjusting it to the lowest setting, it becomes less visible in normal view and completely invisible when zoomed in (Fig2).

Not sure if it is possible to replicate the same with WebGL backend now. It would be great if there is a way to do this. Can someone please help with this? Below are some examples of the plot and corresponding values used. Please let me know if you need more info. Thanks in advance.

Figure command

plt = figure(sizing_mode="scale_both",  plot_width=1300,  max_width=1450,
                 plot_height=550, tools=tools1, active_scroll='xwheel_zoom',
                 x_range=[1, 3095677412], y_range=[-0.8, 0.8], output_backend="webgl"
                 )

Fig1: same Rect glyph’s property setting used in canvas and webgl backend

rect_glyph = Rect(x="x", y="y", width="w", height="h", fill_alpha=0.5, line_width=0.018, hatch_alpha=0.3,  line_alpha=0.050,,  fill_color="blue", name='track')

Fig2: adjusted property setting in webgl (to lowest) to recreate the prev canvas rendering

Rect(x="x", y="y", width="w", height="h", fill_alpha=0.05, hatch_alpha=0.1,  line_alpha=0, line_width=0,fill_color="blue",  name='track')

You are trying to render 1,000,000,000 rectangles in 1,000 pixels using a pixel-based rendering system. Each rectangle is substantially thinner than one pixel, and whether it is displayed or not depends on how its position relates to the centre of the nearest pixel, and is necessarily performed differently for each output backend. This is a very bad idea, please do not do it.

This sort of problem is what datashader was invented to solve. Take a look at it, and when you are comfortable with it look at hvplot which can combine datashader and bokeh to give you interactive plots of your data.

1 Like

@Ian_Thomas Thanks for your response! Just want to clarify that I am not rendering a billion rectangles rather it is my x-axis length. I may have a few thousand rectangle placed randomly so the rectangles are spaced out well on the x-axis. It is just that WebGL is not rendering the colors and alphas the same way as Canvas. So I am assuming there is no solution to make it work with WebGL then?

I did come across datashader for big data. However, my bokeh figure has many other widgets, and glyps added for multiple interactive actions with many custom JS callbacks since it is a standalone HTML and not server based. Bokeh had all the elements that I could use to implement the needs. I wasn’t sure if using Dashshader will provide that flexibility for all my custom Bokeh JS callbacks. Most of the dashshader examples I see are on geospacial maps but I will look more into it and see if can replace some of the glyph elements to improve the performance with the canvas backend.

So I am assuming there is no solution to make it work with WebGL then?

@Gopi1616 That is not evident at all. But in order for us to be able to say anything concrete and specific, you really need to provide a complete Minimal Reproducible Example that can actually be run in order to investigate directly (As well as relevant version information, which is always appropriate to provide in any support question.)