I want to add a Band to the layout in a plot. Minimal example:
df = pd.DataFrame(dict(x = np.arange(100),
y1 = np.random.rand(100),
y2 = np.random.rand(100) + 10)
)
p = figure(y_range = (df.y1.min(), df.y2.max()), plot_height = 400)
source = ColumnDataSource(df)
band = Band(base='x', lower='y1', upper='y2', source=source)
p.add_layout(band)
df.loc[:, "mean_line"] = (df.y1 + df.y2)/2
p.line(x = df.x, y = df.mean_line, legend = "mean")
p.legend.click_policy = "hide"
show(p)
In the above example, when you click on "mean" in the legend then the mean line will hide itself. However, I can't find a way to hide the "Band" object.
I tried the solution suggested here e.g.
li1 = LegendItem(label='red', renderers=[p.renderers[0]])
etc. except I don't think the "Band" has a renederer in the figure as it's added as a layout?
How would I be able to add the band to the legend so I can hide it as I do with the line?
The solutions is to use a virtical area instead of a band.
Here is the code for your example:
import pandas as pd
import numpy as np
from bokeh.plotting import figure, show, output_notebook
from bokeh.models import ColumnDataSource
output_notebook()
df = pd.DataFrame(dict(x = np.arange(100),
y1 = np.random.rand(100),
y2 = np.random.rand(100) + 10)
)
p = figure(y_range = (df.y1.min(), df.y2.max()), plot_height = 400)
source = ColumnDataSource(df)
# band = Band(base='x', lower='y1', upper='y2', source=source)
# p.append(band)
p.varea(x='x', y1='y1', y2='y2', source=source,
fill_alpha=0.1, fill_color='yellow', legend_label = "area")
df.loc[:, "mean_line"] = (df.y1 + df.y2)/2
p.line(x = df.x, y = df.mean_line, legend_label = "mean")
p.legend.click_policy = "hide"
show(p)
If you look very carfully than you can see that the border (fine gray line) is missing. You can add this by drawing two more lines and group them as one legend item. This could look like this:
import pandas as pd
import numpy as np
from bokeh.plotting import figure, show, output_notebook
from bokeh.models import ColumnDataSource, Legend, LegendItem
output_notebook()
df = pd.DataFrame(dict(x = np.arange(100),
y1 = np.random.rand(100),
y2 = np.random.rand(100) + 10)
)
p = figure(y_range = (df.y1.min(), df.y2.max()), plot_height = 400)
source = ColumnDataSource(df)
# band = Band(base='x', lower='y1', upper='y2', source=source)
# p.append(band)
my_area = []
my_area_legend_item = []
my_area.append(p.varea(x='x', y1='y1', y2='y2',
source=source, fill_alpha=0.1, fill_color='yellow'))
my_area.append(p.line(x ='x', y ='y1', color='gray', line_alpha=0.2, source=source))
my_area.append(p.line(x ='x', y ='y2', color='gray', line_alpha=0.2, source=source))
my_area_legend_item.append(LegendItem(label='area',
renderers=[my_area[n] for n in range(len(my_area))]
))
df.loc[:, "mean_line"] = (df.y1 + df.y2)/2
p.line(x = df.x, y = df.mean_line, legend_label = "mean")
p.add_layout(Legend(items=p.legend[0].items+my_area_legend_item, click_policy="hide"))
show(p)