I’m working on a web application that displays Bokeh plots inside movable cards on a dashboard. Each card contains a Bokeh plot generated from Python code. When the view is resized—such as when the browser window size changes or side menus are toggled—the layout adjusts, and the cards are resized accordingly. Initially, my approach was to send the new height and width values to the Python backend whenever the cards were resized, regenerate the Bokeh plots with these fixed dimensions, and reprocess the elements to display the updated plots. However, this method proved inefficient and caused performance issues when many cards are present.
I’m seeking a way to adjust the dimensions of the Bokeh plots inside the cards when they are resized due to view changes, without having to regenerate the plots via Python. I’ve tried setting sizing_mode='stretch_both' when creating the Bokeh figures and adjusting CSS properties to ensure the plots occupy the full available space. This works in many cases but not in all—especially with pie charts. Additionally, it’s important that the legends of the plots also adapt to the sizes of their parent divs. I also attempted to force the plots to resize or re-render using JavaScript but couldn’t find suitable methods in the BokehJS documentation. Triggering a window resize event affects all plots on the page and isn’t efficient.
My question is: How can I adjust the dimensions of the Bokeh plots inside the cards when the cards are resized due to view changes, without regenerating the plots via Python? Is there a recommended way to have the plots resize themselves to fit their containers automatically, including ensuring that legends and elements like pie charts adjust correctly? Any guidance or suggestions would be greatly appreciated.
I’m not sure what this means, there’s not currently any circumstance under which legends will resize or re-position themselves auto-magically. Do you mean after some resizing, the legend can end up “on top” of the plot contents, obscuring it? Then your best bet is probably to put the legend outside the plot region altogether so that cannot happen.
This works in many cases but not in all—especially with pie charts.
Also very unclear what exactly this means in any specific detail either. [1] Screen shots would probably help convey things much more concretely.
I’m sorry for not being more specific in my question (it’s my first time in the community), and thank you in advance for your help.
In some cases (honestly, I haven’t been able to identify a pattern to explain the cause of the problem), when I create a pie chart for use in HTML, part of the chart isn’t visible, even with sizing_mode='stretch_both' (I’ve also tested with scale_both, and the result is the same). The only way I managed to make it work was by using fixed height and width values, but then the chart wasn’t responsive to page resizing. In the shared image, a small portion of the top and bottom parts of the chart ‘did not fit in the space’
Another issue (and I believe they might be related) is the behavior of legends when the width of the div that contains the chart isn’t sufficient (and this happens with all types of charts).
What alternatives do I have to deal with this? My application receives various types of data, so the number of categories can vary greatly. For now, the code that inserts the legend is quite simple:
def plotarLegenda(p, legenda):
leg = p.legend[0]
leg.border_line_color='white'
p.add_layout(leg,'below')
p.legend.orientation = "horizontal"
p.legend.location = "bottom_center"
p.legend.padding = 0
p.legend.margin = 5
p.legend.spacing = 20
if legenda == False: leg.visible = False
return p
“Thanks a lot for your help! If you have any questions, just let me know.”
I’m not sure why the pie chart might be cut off, assuming you are using default data ranges and setting match_aspect=True. Maybe it’s a bug in auto-ranging, maybe it’s a usage issue. I am not able to say anything more concrete without a complete Minimal Reproducible Example that can actually be executed and investigated directly.
I don’t have any especially good options to suggest for the legend cutoff. Currently legends are rendered on the low-level raster canvas, which is why there is no “auto” reflow or anything like that. There are long-term plans to make the legend more DOM-based and then it could participate in the browser’s DOM layout, with all its standard capabilities. But that certainly won’t be done this year. TBH Bokeh was not really built with small plots like this in mind, you might simply want to look at another tool.
Otherwise my only suggestion is to make a vertical legend since legend items typically take up less space vertically, you should be able to fit more in a vertical arrangements. Also as suggested above, you might want to move the legend outside the central plot area.