Bokeh - save plot as svg (ValueError: OutputDocumentFor expects a sequence of Models)

1.3k Views Asked by At

I made a plot in Bokeh but when I try to export it as a svg file I get the following error: OutputDocumentFor expects a sequence of Models.

My code is:

# plot 2D histogram

def plot_hist(ch1, ch2, ch1_name='G3BP1', ch2_name='Nucleocapsid'):
    '''Plot a 2D histogram from two channels'''
    # get histogram data
    df_hist = pd.DataFrame({ch1_name: ch1.ravel(), ch2_name: ch2.ravel()})
    df_hist = df_hist.groupby(df_hist.columns.tolist()).size().reset_index(name='count')
    df_hist['log count'] = np.log10(df_hist['count'])

    # make the plot
    return hv.VLine(10).opts(apply_ranges=True, line_width=2, color = 'black', line_dash = 'dashed') * hv.HLine(10).opts(apply_ranges=True, line_width=2, color = 'black', line_dash = 'dashed')*hv.Points(
        data=df_hist, kdims=['G3BP1', 'Nucleocapsid'], vdims=['log count'],
    ).opts(
        size=10,
        cmap='magma',
        color='log count',
        colorbar=True,
        colorbar_opts={"title": "log₁₀ count"},
        frame_height=500,
        frame_width=500,
        padding=0.05,
        xlabel='G3BP1',
        ylabel='Nucleocapsid',
        fontsize=15,        
    )

# make ROI mask
roi1_nt = (single_cell_roi_rCh[1] > 0) | (single_cell_roi_gCh[1] > 0)
roi1_nt = skimage.morphology.remove_small_objects(roi1_nt, min_size=3)



hv.renderer('bokeh').theme = 'caliber'

plot=plot_hist(im_r[roi1_nt], im_g[roi1_nt])

from bokeh.io import export_svgs
plot.output_backend = "svg"
export_svgs(plot, filename = "plot.svg")

Is there eventually a way to transform the png file saved from this plot in a tiff file with Geotiff?

Thanks in advance for the help.

1

There are 1 best solutions below

0
On BEST ANSWER

It looks like you are using holoviews to create the figure in your function plot_hist(). This is not bokeh object.

Please try to call hv.render() to get the underlying bokeh figure.

The lines below should create a svg file.

import holoviews as hv
from bokeh.io import export_svgs

plot = plot_hist(im_r[roi1_nt], im_g[roi1_nt])
plot = hv.render(plot)
plot.output_backend = "svg"
export_svgs(plot, filename = "plot.svg")

Edit

As @bigreddot metioned, bokeh also has a export_png() tool. In this case the code shhould look like below.

import holoviews as hv
from bokeh.io import export_png

plot = plot_hist(im_r[roi1_nt], im_g[roi1_nt])
plot = hv.render(plot)
export_png(plot, filename = "plot.png")

If your goal is to generate an "tiff" file from "png", you can follow the solution from this question on SO.

from PIL import Image
img = Image.open('plot.png')
img.save('image.tiff')

If the png has an alpha value, this could bring some problems. In this case, check this question about open a png in Pillow.