How to size plots in 3.4; even multi-object example on bokeh website looks broken

I work for a saas company that uses bokeh to render almost all of their reporting. Recently we decided to upgrade from 2.4.3 to 3.4. I’m running into some issues now that figure’s plot_height and plot_width are deprecated.
Is this multi object figure on the following webpage not displaying correctly (scroll down to sizing modes - multiple objects near bottom of page)? Seems like the plot is taking up no width.

We have a similar issue of the plot not taking up any width.

This is some of the code we use to build it out. It’s not a minimal reproducible example but hopefully this is helpful. Previously we were passing plot_height and plot_width into figure and everything worked fine.

self.upper_plot.build_plot(plot_height=300,plot_width=900)                                                                                                                                        
self.lower_plot.build_plot(title='AUR', 
                           x_range=self.upper_plot.plot.x_range, 
                           plot_height=200, 
                           plot_width=900)
                                                                                                                                                                                         
controls = self.widgets.return_widget_list()                                                                                                                                      
inputs = column(*controls)                                                                                                                                                                                                                                                                                                                                         
main_col = column(self.upper_plot.plot,                                                                                                                                                              
self.lower_plot.plot,                                                                                                                                                            
sizing_mode='stretch_width')                                                                                                                                     
display_row = row(inputs, main_col)

Here is an example build_plot function

 def build_plot(self, 
                plot_height=400, 
                plot_width=1200, 
                title='Unit Sales', 
                title_font_size='18pt', 
                label_font_size='12pt', 
                title_align='center', 
                tools="pan, box_zoom, wheel_zoom, reset, hover, save", 
                text_font='calibri', 
                x_range=None):
        """This method build the plot with the current options"""
        try:
            logger.debug('Building Plot')
            if x_range is not None:                                                                                                                                                                  
                plot = figure(height=plot_height,                                                                                                                                                                
                              width=plot_width,                                                                                                                                                                  
                              sizing_mode='stretch_width',                                                                                                                                                          
                              x_axis_type='datetime',
                              title=title,                                                                                                                                                                       
                              tools=tools,                                                                                                                                                                        
                              x_range=x_range)                                                                                                                                                 
            else:                                                                                                                                                                                  
                plot = figure(height=plot_height,                                                                                                                                                                 
                              width=plot_width,                                                                                                                                                                   
                              sizing_mode='stretch_width',                                                                                                                                                          
                              x_axis_type='datetime', 
                              title=title,                                                                                                                                               
                              tools=tools)
            plot.title.text_font_size = title_font_size
            plot.title.align = title_align                                                                                                                                                     
            plot.axis.major_label_text_font_size = label_font_size
            plot.xaxis[0].formatter.years = ['%Y-%m']                                                                                                                                          
            plot.xaxis[0].formatter.months = ['%Y-%m']                                                                                                                                         
            plot.xaxis[0].formatter.days = ['%Y-%m-%d']                                                                                                                                        
            plot.toolbar.logo = None
            plot.title.text_font = text_font
            plot.axis.major_label_text_font_size = label_font_size
            plot.axis.major_label_text_font = text_font
            plot.yaxis[0].formatter.use_scientific = False
            self.plot = plot                                                                                                                                                                   
            self.hovertool()
        except Exception as e:                                                                                                                                                                 
            error_client.report_exception()
            logger.error('Encountered error: %s', e)

2.4.3 to 3.4 is a big jump, I can easily imagine your code needing some updates across major revisions. But the docs page also looks like a bug, so the best thing would be to submit a GitHub Issue with full details. This is the sort of thing we’d hopefully be able to get out in a patch 3.4.1 release fairly soon.

Oh yea I agree it’s a huge jump. The reasoning for such a big jump actually comes out of a different issue with numprocs >1 (bokeh server, embedded into a flask app, load balanced by nginx) that seems to be resolved in bokeh > 3.0

Just noting that numprocs>1 together with nginx load balancing seems redundant. Using numprocs>1 is a “poor man’s load balancer”, useful for when someone doesn’t want to go to the effort to stand up a real load-balancer like Niginx.

If I’m running behind Nginx, I’d just run more bokeh serve processes on different ports (as many as you need) and let Nginx do what it is designed to do.

That’s a really valuable perspective! We aren’t running up against a limit of available ports. So you would say that numprocs >1 would more often get in the way/ be superfluous to a network load balancer? I think there is an argument for a scenario where both work together

--num-procs just forwards to tornado’s num_processes which does not really afford any sort of load balancing AFAIK, so it would be possible for the “internal” tornado processes to be utilized in an unbalanced way. In any case, for me, at least, it’s added (unnecessary) complexity, which is always good to try and avoid.

@Michelle_Flanner will you be able to submit a GitHub issue regarding the bug? (it’s preferable for issues to be reported by end-users)

Hi Bryan,
Yes I would be happy to submit a github issue. I’ll make a minimal reproducible example which shouldn’t take too long.

1 Like

I had similar issues when I upgraded from 2.4 to 3.3. Most of them were resolved by adding sizing_mode='stretch_width' in layout functions. In your case, I suspect if you add it to display_row = row(inputs, main_col) it might fix the problem.