Christian Aichinger
Christian Aichinger

Reputation: 7227

Add additional curve to bokeh chart

Can I add an additional line to a bokeh.chart.Area graph? Or, equivalently, is there a way to convert a chart to a normal figure, so I can manually draw into it?

I have a diagram like in this question and need to add an additional curve. It should show up as a single line, not as part of the stacked area plot.

Bokeh: 0.11.1,
Python:2.7

Upvotes: 2

Views: 2838

Answers (1)

Jake
Jake

Reputation: 951

You can add new glyphs (in your case a bokeh.models.glyphs.Line object) to a chart using the add_glyph(data_source, glyph) method of the chart object:

# Create a data source
ds = bokeh.models.sources.ColumnDataSource(dict(x=df['date'], y=[0,3,2]))
# Define the line glyph
line = bokeh.models.glyphs.Line(x='x', y='y', line_width=4, line_color='blue')
# Add the data source and glyph to the plot
p.add_glyph(ds, line)

However, if you just add that code, the line will show up in your plot but there won't be a corresponding entry in the legend. To also get a legend entry, you need to add the new entry to the internal _legend list of the chart object and then add the updated legend.

Here's your example:

from datetime import datetime
import pandas as pd
from bokeh.charts import Area, show, output_notebook
import bokeh.models.glyphs
import bokeh.models.sources

df = pd.DataFrame()
df['date'] = [datetime(2016, 1, 1), datetime(2016, 1, 2), datetime(2016, 1, 3)]
df['v1'] = [1, 2, 3]
df['v2'] = [4, 4, 3]

p = Area(df, x='date', y=['v1', 'v2'], title="Area Chart",
         xscale='datetime', stack=True,
         xlabel='time', ylabel='values',
         # We need to disable the automatic legend and add the correct one later
         legend=False)

# Create a data source
ds = bokeh.models.sources.ColumnDataSource(dict(x=df['date'], y=[0,3,2]))
# Define the line glyph
line = bokeh.models.glyphs.Line(x='x', y='y', line_width=4, line_color='blue')
# Add the data source and glyph to the plot
p.add_glyph(ds, line)

# Manually update the legend
legends = p._builders[0]._legends
legends.append( ('x',[p.renderers[-1]] ) )
# Activate the legend
p.legend=True
# Add it to the chart
p.add_legend(legends)

output_notebook()
show(p)

Upvotes: 4

Related Questions