Download Holoview graph

Hi, I am trying to build an application with react and flask. One of the functionality is to download this holoview graph as a png, the issue is that I am building a customized save button instead of using the save button embedded with graph.

To download the image, I need something like a base-64/blob version of this image, I am wondering if there are any methods that can help me convert a holoview chart to a base64 string in python.

On the Python side you can hv.save the file. For example using the matplotlib backend and to .svg. Or Bokeh and .png. Then you can transfer the result over your REST API to the frontend.

You can use something along the lines of

import hvplot.pandas
import pandas as pd
import holoviews as hv
import base64
import pathlib

data = pd.DataFrame({"x": [1,2,3,4]})
plot = data.hvplot()

file=pathlib.Path("out.svg")
hv.save(plot, filename=file, backend="matplotlib")
svg = file.read_text()
print(svg)
svg_64_encode = base64.b64encode(svg.encode())
print(svg_64_encode)

You should make it faster and more robust using BytesIO or StringIO instead of saving to a file.

For more info check out the documentation of hv.save Exporting and Archiving.

Hi Marc, thank you for your wonderful response, yes, I do look for a solution that doesn’t need to download and read the image again, like what you mention, the BytesIO solution, Is it possible that you can just show me how I might convert a hvplot a BytesIO or StringIO with concrete code example

@Marc I want to download the output of chatbot that is build using Panel in my local system. Here is code

cb = ChatBot()

file_input = pn.widgets.FileInput(accept='.pdf'or '.PDF')
button_load = pn.widgets.Button(name="Load DB", button_type="primary")
button_clearhistory = pn.widgets.Button(name = "Clear History", button_type = 'warning')
# button_download = pn.widgets.FileDownload
button_clearhistory.on_click(cb.clr_history)
inp = pn.widgets.TextInput(placeholder = "Enter text here")

bound_button_load = pn.bind(cb.call_load_db, button_load.clicks)
conversation = pn.bind(cb.convchain, inp)

jpg_pane = pn.pane.Image('./img\convchaib.jpg')

tab1 = pn.Column(
    pn.Row(inp),
    pn.layout.Divider(),
    pn.panel(conversation, loading_indicator=True, height=1000),
    pn.layout.Divider()
)

tab2= pn.Column(
    pn.panel(cb.get_lquest),
    pn.layout.Divider(),
    pn.panel(cb.get_sources ),
)
tab3= pn.Column(
    pn.panel(cb.get_chats),
    pn.layout.Divider(),
)
tab4=pn.Column(
    pn.Row( file_input, button_load, bound_button_load),
    pn.Row( button_clearhistory, pn.pane.Markdown("Clears chat history. Can use to start a new topic" )),
    pn.layout.Divider(),
    pn.Row(jpg_pane.clone(width=800))
)
dashboard = pn.Column(
    pn.Row(pn.pane.Markdown('# ChatWithYourData_Bot')),
    pn.Tabs(('Conversation', tab1), ('Database', tab2), ('Chat History', tab3),('Configure', tab4))
)
dashboard

This should probably be in a new thread, but see HoloViz Blog - Panel AI Chatbot Tips: Memory and Downloadable Conversations