☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

Trigger a SaveTool action via CustomJS? Other ways?

Community Support
gmerritt123
gmerritt123

What am I trying to do?

Accomplish the ‘save’ action of a saveTool on a figure/plot via CustomJS (e.g. when the user clicks a button, I need to do execute a series of things, including a png export of the current view.

What I’ve set up/sketched out → three (not working) ideas in the CustomJS code:

from bokeh.plotting import figure, save
from bokeh.models import CustomJS, Button
from bokeh.layouts import column
f = figure()
f.scatter(x=[1,2,3],y=[1,2,3])
btn = Button(label='Click me to save image of f??')

cb = CustomJS(args=dict(f=f
                        ,st=f.tools[3] #the saveTool instance attached to the figure
                        )
              ,code='''
              console.log(f)
              console.log(st)
              
              //IDEA 1 --> st seems to have a "do"/"doit" method?
              st.do({action:'save'}) // ???
              
              //IDEA 2 --> "trigger_event" on figure?
              
              f.trigger_event({'event_name':'save'}) //?? doesn't seem to be a "save" event etc?
              
              
              //IDEA 3 --> mimic SaveTool.ts source code? --> Lines 16-21 here  https://github.com/bokeh/bokeh/blob/branch-3.1/bokehjs/src/lib/models/tools/actions/save_tool.ts
              
              const blob = this.parent.export().to_blob() 
              // "this.parent" in the source code is I believe something to do with the figure's "PlotView" 
              // but I don't know how to access that from here
              const link = document.createElement("a")
              //the rest of the source code i think i understand/can use?
              link.href = URL.createObjectURL(blob)
              link.download = 'yourimage' // + ".png" | "svg" (inferred from MIME type)
              link.target = "_blank"
              link.dispatchEvent(new MouseEvent("click"))
              
              
              ''')
btn.js_on_click(cb)
save(column([btn,f]))

I’m not sure which of the three ideas is best approach/possible or if any of them will accomplish what I’m shooting for. I am also (evidently) very lost on syntax/proper querying of what I need to query for all three… Any guidance much appreciated!

Thanks…

⌁   Link to post
gmerritt123
gmerritt123

Simultaneously frustrating but satisfying… as soon as you post the question you find the answer yourself.

I needed to read into “do” a bit more. st.do.emit() will execute the save action. The only other tricky part was that you need to initialize the savetool with a dummy filename (“stuff” in my example below). That way you can update its filename property freely in the CustomJS, which will then let you bypass the filenaming prompts you may get.

from bokeh.plotting import figure, save,show
from bokeh.models import CustomJS, Button
from bokeh.layouts import column
f = figure()
f.scatter(x=[1,2,3],y=[1,2,3])
btn = Button(label='Click me to save image of f??')
f.tools[3].filename = 'stuff'
cb = CustomJS(args=dict(f=f
                        ,st=f.tools[3] #the saveTool instance attached to the figure
                        )
              ,code='''             
              st.filename = 'stuff_but_different'
              st.do.emit()
              ''')
btn.js_on_click(cb)
show(column([btn,f]))
⌁   Link to post

End of archived discussion · Replies are disabled