The issue above only concerned the relative order of entire glyphs, e.g. how to relatively order entire sets of elements each generated by separate, different calls to calls to the circle glyph method. The issue was not about the order the individual circle elements drawn for one call to the circle method.
In fact, there is no mechanism to specify this. In general the order of individual items for a single glyph method can be affected by many things: presence or absence of active selections, CDS views and filters, interactive level-of-detail decimation, hover highlighting activations, webgl vs canvas vs svg rendering backend, muted status, and point culling from spatial indexing, among others. Because of this complexity, there is no guarantee regarding the order that a glyph will draw its individual elements, and no way to exert control over this order.
If you need to control the placement of, say, individual circles on the screen, you will have to have separate calls to circle(...) for each, and order the glyph renderers for those circles in the renderers list (as described in the issue). I don’t have any other practical recommendations to offer . Bluntly, if this is not workable then you will probably need to look at other tools besides Bokeh.
At the extreme you could in principle create a custom extension ti draw whatever you want in whatever order you want, but for you what you are describing you’d have to jettison a huge amount of existing BokehJS machinery. It would be a highly nontrivial undertaking, and in addition, the BokehJS API is not yet entirely stabilized so it might require future upkeep. ↩︎
" If you need to control the placement of, say, individual circles on the screen, you will have to have separate calls to circle(...) for each, and order the glyph renderers for those circles in the renderers list (as described in the issue)."
I don’t entirely understand what you mean by this. Could you explain?
I.e. is there a minimal computational cost method to tell js to change the order of display?
I don’t really understand the question. As I mentioned there are several interactive features that intersect all at once that can all influence the order. As an example: when there is an active selection, all the selected points are drawn as one batch, and all the unselected points in another batch, i.e. “out of order”. It’s not about computation cost, it’s about complexity that is incompatible with a simple order notion.
Since you mentioned streaming, I had one idea that might be useful in case it would suffice to split the glyphs up into just a few “sub-levels” within the glyph rendering level that Bokeh implicitly cares about:
have one CDS, that you stream data, including a column for what “sub-level”
make multiple calls glyph calls, with a GroupFilter keyed to one “sub-level”
these glyphs should be added by you in the order you want the “sub-levels” to appear
That might work. I am not aware of anyone every trying, or for that matter, trying to use CDS filters together with streaming. As with any large project, the less well-traveled areas of the project are always more likely to have not-yet-know issues. You’d just have to try and see.
I see the answer to my question. I meant if js theoretically supports z-order display without needing to re-render the plot. I.e. if there are no hardcoded dead-ends that would prevent that. But as it can bring to front say on hover, it should theoretically be able to do what I am after.
Thanks for idea. However, I need to re-order up to 10000 glyphs individually. Streaming them alongside the app is not a bottleneck, so was hoping that ordering them at the same time is possible too.
There might also be a misunderstanding here. Bokeh is a raster drawing tool that draws on a raster canvas. The entire plot (i.e. the canvas) is always completely re-drawn on any change, including streaming. The savings from stream come from reduced network traffic (i.e. sending only new data points), not from any “partial” drawing updates.
I’m honestly not sure why that would work. I’d expect a full assignment e.g. cds.data = new_data would be necessary to automatically trigger re-render, but then also I’d expect that to trigger and infinite callback cascade since the callback is on data. But if you say it is working for you I’ll take your word.
The data change on the python side triggers both a redraw, and the CustomJS callback execution. I suppose what might be the case is that the CustomJS callback just happens to be the one executing first. That’s just speculation, but it would explain things. However, there is no guarantee of that order so as you note it’s probably not reliable to rely on.
Setting some other property that can trigger a redraw is a way avoid the callback cylce, it’s slightly hacky but will get the job done. There is in principle a request_redraw that can be called on plot views, but I have no direct experience with it, see this comment for some info: