Missing file errors when using bokeh save to png/svg

This might be more suitable for the Bokeh discourse, but I’m trying to set up a way of exporting a Bokeh figure to svg through panel. While the figure exports ok, I’m seeing a bunch of browser errors and file missing errors when it gets triggered. The file missing errors seem to all be Panel related.

This is a minimal reproducible example (running on Panel 1.2.3 and Bokeh 3.2.2 – when I try to upgrade I’m having unrelated selenium problems)

import panel as pn
import pandas as pd
from bokeh.models import ColumnDataSource
from bokeh.transform import linear_cmap
from bokeh.plotting import figure
from bokeh.io import export_svg
import bokeh.palettes
import param

pn.config.notifications = True
pn.extension('tabulator', 'jsoneditor')

dict = {
    'col_no' : [1, 2, 3, 1, 2, 3, 1, 2, 3],
    'row_no' : [1, 1, 1, 2, 2, 2, 3, 3, 3],
    'value' : [1, 2, 3, 4, 5, 6, 7, 8, 9]}
data = pd.DataFrame(dict)

class test_app(param.Parameterized):
    heatmap_ready = param.Boolean()
    heatmap_go = param.Action(lambda x: x.param.trigger('heatmap_go'))
    download_go = param.Action(lambda x: x.param.trigger('download_go'))
    param_dict = param.Dict(dict)

    @param.depends('heatmap_go', watch = True)
    def set_ready(self):
        self.heatmap_ready = True
    
    @param.depends('heatmap_go')
    def show_heatmap(self):
        if self.heatmap_ready:
            #return 'ready'
            p = figure(
                active_drag = None,
                y_axis_location = 'right',
                x_axis_location='above',
                frame_width = 75 * len(data.col_no.unique()),
                frame_height = 75 * len(data.row_no.unique()))
            #p.output_backend = 'svg'
            p.rect(x="col_no", 
                y="row_no", 
                width=1, 
                height=1, 
                source=ColumnDataSource(self.param_dict), 
                fill_color = linear_cmap(
                    palette='Viridis256', 
                    field_name = 'value',
                    low = 1,
                    high = max(self.param_dict['value'])),
                line_color='white',
                line_width=1)
            return pn.pane.Bokeh(p)
        else:
            return 'not ready'
        
    @param.depends('download_go', watch = True)
    def download_heatmap(self):
        if not self.heatmap_ready:
            pn.state.notifications.warning('not ready!')
        else:
            p = figure(
                active_drag = None,
                y_axis_location = 'right',
                x_axis_location='above',
                frame_width = 75 * len(data.col_no.unique()),
                frame_height = 75 * len(data.row_no.unique()))
            #p.output_backend = 'svg'
            p.rect(x="col_no", 
                y="row_no", 
                width=1, 
                height=1, 
                source=ColumnDataSource(self.param_dict), 
                fill_color = linear_cmap(
                    palette='Viridis256', 
                    field_name = 'value',
                    low = 1,
                    high = 9),
                line_color='white',
                line_width=1)
            export_svg(p, filename = 'minimum.svg')
            pn.state.notifications.success('woohoo!')
    
    def view(self):
        return pn.template.VanillaTemplate(
            title = 'test',
            main = pn.Row(
                self.show_heatmap,
                #pn.Column(
                    pn.widgets.Button.from_param(
                        self.param['heatmap_go'],
                        button_type = 'primary',
                        width = 80),
                    pn.widgets.Button.from_param(
                        self.param['download_go'],
                        name = 'Download',
                        button_type = 'primary',
                        width = 80),
                    pn.widgets.JSONEditor.from_param(
                        self.param['param_dict'], 
                        name = 'Values',
                        width = 300)),
            logo = 'htviz/imgs/icon.png'
        ).servable()
    
test_app().view()
    

The python console errors I see are:

Might be related to UndefinedError while saving a panel object to html file · Issue #6643 · holoviz/panel · GitHub, this used to work fine :confused:

1 Like

Yeah this sure does seem like it’s related!