Python Bokeh: remove toolbar from chart - python

Note from maintainers: The specifics of this question concern the bokeh.charts API which is obsolete and was removed several years ago. In modern Bokeh, specify toolbar_location:
p = figure(toolbar_location=None)
OBSOLETE:
I don't seem to be able to remove the toolbar from a bokeh Bar chart. Despite setting the tools argument to None (or False or '') I always end up with the bokeh logo and a grey line, e.g. with this code:
from bokeh.charts import Bar, output_file, show
# prepare some data
data = {"y": [6, 7, 2, 4, 5], "z": [1, 5, 12, 4, 2]}
# output to static HTML file
output_file("bar.html")
# create a new line chat with a title and axis labels
p = Bar(data, cat=['C1', 'C2', 'C3', 'D1', 'D2'], title="Bar example",
xlabel='categories', ylabel='values', width=400, height=400,
tools=None)
# show the results
show(p)
However, when I try the same with a bokeh plot, it works perfectly fine and the toolbar is gone, e.g. with this code:
from bokeh.plotting import figure, output_file, show
output_file("line.html")
p = figure(plot_width=400, plot_height=400, toolbar_location=None)
# add a line renderer
p.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=2)
show(p)
Does anyone know what I'm doing wrong?

If you want to remove the logo and the toolbar you can do:
p.toolbar.logo = None
p.toolbar_location = None
Hope this resolves your problem

On any Bokeh plot object you can set:
p.toolbar_location = None

Related

simple 1 layer area chart in bokeh

I am trying to create a simple area chart in bokeh (1 layer)
My attempt
df_example = pd.DataFrame(data= [['01-01-2018',10],['02-01-2018', 5 ], ['03-01-2018',7]], columns = ['date', 'value'] )
p = figure(plot_width=600, plot_height=400, x_range = df_example['date'])
p.Area(df_example, x='date', y='value')
show(p)
I get an error
AttributeError: 'Figure' object has no attribute 'Area'
Is the Area chart seems to be not available in bokeh anymore
Can anybody demonstrate how to get this type of chart please?
Bokeh recently added a varea_stack glyph method:
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, show
source = ColumnDataSource(data=dict(
x=[1, 2, 3, 4, 5],
y1=[1, 2, 4, 3, 4],
y2=[1, 4, 2, 2, 3],
))
p = figure(plot_width=400, plot_height=400)
p.varea_stack(['y1', 'y2'], x='x', color=("grey", "lightgrey"), source=source)
show(p)

How to use a CDS column to set the "line_dash" of a Multiline glyph?

I am plotting Multilines with the method multi_line.
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource
source = ColumnDataSource(data=dict(
x=[3, 3],
y=[4, 4],
xs1=[[1, 2, 3], [2, 3, 4]],
ys1=[[6, 7, 2], [4, 5, 7]],
xs2=[[8, 9], [10, 11, 12]],
ys2=[[6, 7], [7, 8, 9]],
color=['red', 'green'],
width=[5, 1],
dash=['solid', 'dashed']
)
)
p = figure(
plot_width=400,
plot_height=400,
tools='lasso_select,pan,wheel_zoom'
)
p.multi_line(
xs='xs1',
ys='ys1',
source=source,
color='color',
line_join='round',
line_width='width', # this is working with the column name, despite the documentatio say nothing
# line_dash='dash' # this is not working
)
show(p)
A column for color, alpha or line_width can be set on multilines source CDS in order to plot each line in a different way. But this cannot be applied to the line_dash attribute. I would like to make the main line solid and the rest dashed.
If I use the glyph line for this main lines then I will lose performance because I need to update more than one glyph at the same time on each plots.
On the other hand I think there are something missing in the documentation about line_width because a CDS column can be assigned to this method argument and it works:
alpha (float) – an alias to set all alpha keyword args at once
color (Color) – an alias to set all color keyword args at once
>> line_width (float) - should this be added because it works with CDS columns?
Is there a way to assign a column for the line_dash attribute?
I didn´t test the rest of attributes in depth.
Although you are asking in relation to MultiLine, this has the same answer as Can the line dash of a segment plot be defined by source data? which is that "vectorizing" the line_dash property is not currently supported (as of 0.12.16) If you want to have different line dashes for now you will have to make separate calls to line.

Add hover to Bokeh without losing rest of tools

So with Bokeh I can do something like this to create a hover option:
From bokeh.models import HoverTool #add hover functionality
Hover = HoverTool(tooltips=[(name1:#column1), (name2:#columns2)])
Plot = figure(tools=[hover])
Plot.circle(x,y,hover_color=’red’)
However, by doing so, I lose the standard tools you get when you call figure() like pan, box_zoom, wheel_zoom, etc. I know I can add them back 1 by 1 inside the figure(tools=[]), but is there a way to only add hover to the rest of the default tools of figure(), after it is defined??
Thanks!
Use the add_tools() method, as outlined in the docs:
https://docs.bokeh.org/en/latest/docs/user_guide/tools.html#specifying-tools
Slightly modified example from the docs:
from bokeh.plotting import figure, output_file, show
from bokeh.models import HoverTool
output_file("toolbar.html")
# create a new plot with the toolbar below
p = figure(plot_width=400, plot_height=400,
title=None, toolbar_location="below")
p.circle([1, 2, 3, 4, 5], [2, 5, 8, 2, 7], size=10)
p.add_tools(HoverTool())
show(p)

Example of building Bokeh panels with complex layouts?

I am trying to make Bokeh Panels that have relatively complex layouts, so I tried moving half of my current layout into one Panel and half into another just to play around, like so:
selects = HBox(top_users_select, new_users_select, t1_users_select, t2_users_select, top_recent_users_select)
tab1 = Panel(inputs)
tab2 = Panel(VBox(HBox(plot2, plot1, plot3, plot4), HBox(plot5, plot6, plot7, plot8), data_table))
tabs = tabs(tab1, tab2)
show(tabs)
However this is giving me the following error:
File "main_panel.py", line 589, in <module>:
tab1 = Panel(inputs) Traceback (most recent call last):
File "/Users/joe/anaconda3/lib/python3.5/site-packages/bokeh/application/handlers/code_runner.py", line 71, in run
exec(self._code, module.__dict__)
File "/Users/joe/Desktop/scripts/src/main/python/Bokeh apps/insights/main_panel.py", line 589, in <module>
tab1 = Panel(inputs)
TypeError: __init__() takes 1 positional argument but 2 were given
I am fairly new to Bokeh, and looking at the docs I don't know exactly how to parse this error and get around it. Can someone point me to an example of laying out fairly complex grids in a Bokeh panel or tell me what the error means and how I can address it?
You can use row or column to create complex layouts within tabs.
You can even mix them like row(column(button1, button2), button3)
Example:
from bokeh.models.widgets import Panel, Tabs, Toggle, TextInput
from bokeh.io import output_notebook, show
from bokeh.plotting import figure
from bokeh.layouts import column, row
p1 = figure(plot_width=300, plot_height=300)
p1.circle([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=20, color="navy", alpha=0.5)
p2 = figure(plot_width=300, plot_height=300)
p2.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=3, color="navy", alpha=0.5)
toggle1 = Toggle(label="Foo", button_type="success")
toggle2 = Toggle(label="Foo", button_type="warning")
text_input = TextInput(value="default", title="Label:")
tab1 = Panel(child=row(p1,toggle2), title="circle")
tab2 = Panel(child=column(p2,toggle1, text_input), title="line")
tabs = Tabs(tabs=[ tab1, tab2 ])
output_notebook()
show(tabs)
See https://docs.bokeh.org/en/latest/docs/user_guide/layout.html for more details
I think you want to write selects instead of inputs, but there are basically some things wrong with your declaration.
Look at the examples at http://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html#tabs
from bokeh.models.widgets import Panel, Tabs
from bokeh.io import output_file, show
from bokeh.plotting import figure
output_file("slider.html")
p1 = figure(plot_width=300, plot_height=300)
p1.circle([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=20, color="navy", alpha=0.5)
tab1 = Panel(child=p1, title="circle")
p2 = figure(plot_width=300, plot_height=300)
p2.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=3, color="navy", alpha=0.5)
tab2 = Panel(child=p2, title="line")
tabs = Tabs(tabs=[ tab1, tab2 ])
show(tabs)
Your input in Panel should be assigned to child= and a Panel needs a title=.
Also change
tabs = tabs(tab1, tab2)
to
tabs = Tabs(tabs=[tab1,tab2,tab3,tab4])

Style part of glyph

In the minimal example below, how can I highlight, say, the highest point by changing its fill color to red? I know in this case it's easy enough just to draw over the old glyph: p.circle(3, 8, fill_color='red'), but my actual plot is more complicated. So I'm hoping to change something inside the variable r instead, if this is possible.
from bokeh.plotting import figure, output_file, show
output_file("dimensions.html")
p = figure(plot_width=700)
p.plot_height = 300
r = p.circle([1, 2, 3, 4, 5], [2, 5, 8, 2, 7], size=10)
show(p)
If you want just one circle to be a different color, then there are only two options:
send all the colors:
p.circle(x, y, color=["blue", "blue", "red", "blue", "blue"], size=10)
Have separate renderers:
p.circle([1, 2, 4, 5], [2, 5, 2, 7], color="blue", size=10)
p.circle(x=3, y=8, color="red", size=10)
There was some exciting new work recently added to GH master to make a start for adding "computed transforms" so in the near future it should be possible to define a custom color mapper for a single glyph, but that functionality does not exist yet as of version 0.11.1

Categories

Resources