Setting: don´t plot figures without renderers

Hello!

If a figure has no renderers, the following warning code is prompted:
WARNING:bokeh.core.validation.check:W-1000 (MISSING_RENDERERS): Plot has no renderers: Figure(id=‘1004’, …)

Is there a setting so that figures without renderers don´t get plotted?

The solution I thought of at the moment is to add all figures to a list (or list of lists) and then check each element of the list if there is a warning generated, like:

for plt in plots:
if bokeh.core.validation.check_integrity([plt]):
plots.remove(plt)

However that does not work unfortunately.
I would be really happy about any help. Thank you

Is there a setting so that figures without renderers don´t get plotted?

What do you mean by this more specifically? Do you want empty figures to be completely ignored (not even serialized), serialized but ignored in the frontend, make them invisible until renderers are added?

The solution you tried won’t work, because you are removing plots from an unrelated data structure. You would have to remove them from the layout they are a part of, but without more context it’s hard to tell anything more specific.

Sorry about not being specific.
I think option two is best because only after creating the figure one can know (at least in my usecase) know if there are renderers in the plot.

Context: I want to set up a dashboard to monitor different parameters. However not all parameters are measured in every case. This is why I want to exclude the figures from the page, if they show no information for the specific case. The data won´t be added in the future.

I already managed to add all plots into a list, but I the check for empty plots did not work.

#Get data....

source = ColumnDataSource(df)

plots=[]
plots.append(bokeh_chart(source, pltcfg[0], title='plot1'))
x_dash=plots[0].x_rangeresponse time
plots.append(bokeh_chart(source, pltcfg[1], x_range=x_dash, title='plot2'))
plots.append(bokeh_chart(source, pltcfg[2], x_range=x_dash, title='plot3'))
###more figures

#check here for empty plots (does not work)
for plt in plots:
    if bokeh.core.validation.check_integrity([plt]):
        plots.remove(plt)

lay=layout(children=[[plots]], sizing_mode='stretch_width')
show(lay)

@JohannesFischer

The following simple example accomplishes what you want if I understand your general requirement.

The code generates figures and then handles them in a layout sequentially based on how I interpret your code/workflow.

The second option, currently commented-out, would keep even empty figures in the layout, but they wouldn’t take up any screen space b/c they have visibility set to False. They will however still generate warnings about having no renderers. The upside of this approach is you could dynamically make them visible if some aspect of the app allowed for user data to be associated with the plot at a later time.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
"""
import numpy as np

from bokeh.plotting import figure
from bokeh.layouts import column
from bokeh.io import show


x = np.arange(start=0.0, stop=1.0, step=0.01)

ll = []

for i in range(10):
    p = figure(width=500, height=100, x_axis_label='x', y_axis_label='F{:}'.format(i))
    ll += [p]

    if i % 2:
        p.line(x, np.sin(2.0*np.pi*i*x))

for i,fig in enumerate(ll):
    if not fig.renderers:
        ll.pop(i)             # OPTION 1 (remove empty figure)
        #fig.visible = False  # OPTION 2 (hide empty figure)

show(column(ll))

OUTPUT

3 Likes

@_jm

Thank you, that is exactly what is was looking for!

Just FYI, I added an extra list to properly remove all the missing plots. I found that your solution skips a plot after removing a plot from the list.

to_remove=[]
for fig in ll:
    if not fig.renderers:
        print(f'{fig.title.text} plot has no data, not shown in the dashboard')
        to_remove.append(fig)

ll = [e for e in plots if e not in to_remove] #removes elements by assigning new list
1 Like

Of course, you are absolutely correct. The logic included in the example to remove elements from the list of figures to draw only works for that special pattern of alternating keep/discard cases and not the general case.

Thanks for correcting the record (and possibly helping anyone else who has the same requirement).

Great that you have a solution that works for you. Good luck moving forward with your software.

Also just FYI there is a WIP PR open to make it possible to check for validation issues without also raising exceptions or warnings:

that might be useful to simplify this in the future.