bokeh
bokeh copied to clipboard
Document width_policy, heigh_policy
#4407 was closed in the large layout PR work, but some of the features such as width_policy and height_policy never got documented fully, or examples added.
As requested, here is a complete example for width_policy and heigth_policy in action. Happy to help!
"""Example for Bokeh width_policy and heigth_policy.
We want to create a 2x2 gridplot that stretches with the browser window.
Each figure has a RangeTool below that should stay at a fixed height.
"""
import numpy as np
from bokeh.models import ColumnDataSource, RangeTool
from bokeh.plotting import figure, output_file, show
from bokeh.layouts import column, gridplot
from bokeh.models.ranges import Range1d
def get_select_RangeTool(p, x, y, source):
"""Return a figure that uses the range_tool to control the figure p."""
select = figure(plot_height=45, y_range=p.y_range, y_axis_type=None,
tools="", toolbar_location=None,
background_fill_color="#efefef",
# This is where the magic happens:
height_policy="fixed", width_policy="fit",
)
select.line(x, y, source=source)
# Create a RangeTool that will be added to the "select" figure
range_tool = RangeTool(x_range=p.x_range) # Link figure and RangeTool
range_tool.overlay.fill_color = "navy"
range_tool.overlay.fill_alpha = 0.25
select.ygrid.grid_line_color = None
select.add_tools(range_tool)
select.toolbar.active_multi = range_tool
return select
def get_figure_with_select():
"""Return a column of a figure with its select RangeTool."""
# Create data
x = np.linspace(0, 4*np.pi)
y = np.sin(x)
source = ColumnDataSource(data=dict(x=x, y=y))
# Set up plot
p = figure()
p.x_range = Range1d(min(x), max(x)) # Bug? This should not be necessary!
p.line('x', 'y', source=source)
select = get_select_RangeTool(p, 'x', 'y', source)
return column(p, select, sizing_mode='stretch_both')
# Create four figures to add to a 2x2 gridplot
fig_list = [get_figure_with_select(), get_figure_with_select(),
get_figure_with_select(), get_figure_with_select()]
grid = gridplot(fig_list, ncols=2, sizing_mode='stretch_both')
# Create output
output_file('Example_height_policy.html', title='Example height_policy')
show(grid)
As a bonus, there is a bug report hidden in there. Without the line
p.x_range = Range1d(min(x), max(x)) # Bug? This should not be necessary!
...this error comes up:
range_tool = RangeTool(x_range=p.x_range) # Link figure and RangeTool
ValueError: expected an instance of type Range1d, got DataRange1d(id='8713', ...) of type DataRange1d
At least this seems like a bug to me. Should RangeTool not be able to accept DataRange1d? Hacking the Range of the original figure to Range1d is a really weird workaround.
Should I open a new issue about this? Regards!
At least this seems like a bug to me. Should RangeTool not be able to accept DataRange1d?
They are a bit at odds. A DataRange1d is for automatically setting the range extent based on the available data, and a range tool is about explicitly controlling the range extent, completely ignoring the data.
given this is layout-related and layout is being revamped for 3.x, I am going to kick this down the road cc @tcmetzger @mattpap