I would like to know if there is a way to add markers to multiline for bokeh. I can get the multiple lines but then p.circle() doesn't seem to work on list of lists. Here is a sample:
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource
from bokeh.palettes import Spectral6, Spectral11
numlines = 2
mypalette = Spectral6[0:numlines]
data = {'x_values': [[1, 2, 3], [1,2,3]],
'y_values': [[1, 2, 3], [4 ,5, 6]], 'labels': ['a', 'b'], 'line_color': mypalette}
source = ColumnDataSource(data=data)
p = figure()
p.multi_line(xs='x_values', ys='y_values', line_color='line_color', source=source)
show(p)
As of Bokeh 0.13.0 there is not. You would need to call p.circle, p.square, etc. for each "sub" line in the multi-line.
Related
I have tried changing multiple parameters(arguments) but this doesn't work.
The bokeh version is 1.3.4.
from bokeh.layouts import column
from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource, Slider, Select
from bokeh.plotting import Figure, output_notebook, show
import numpy as np
a = 20
bokeh_tools = "pan,wheel_zoom"
output_notebook()
plot_2s = ColumnDataSource(data=dict(x=[1, 2, 3], y=[1, 2, 3]))
plot_3s = ColumnDataSource(data=dict(x=[3, 4, 5], y=[1, 2, 3]))
line_source = ColumnDataSource(data=dict(x=[1, 2, 3], y=[1, 2, 3]))
plot_1 = figure(x_axis_type="datetime", plot_width=800, tools=bokeh_tools, title="plot_1")
plot_1.line(x = 'x', y='y', source=plot_2s)
plot_2 = figure(x_axis_type="datetime", plot_width=800, tools=bokeh_tools, title="plot_2")
plot_2.line(x='x', y='y', source=line_source)
select = Select(title="SELECT", options=["val1", "val2"])
column = column(select, plot_2)
show(column)
select.callback = CustomJS(args={"cds2": plot_2s, "cds3": plot_3s, "ls": line_source}, code="""
if(cb_obj.value === "val1"){
ls.data = cds2.data;
}else if(cb_obj.value === "val2"){
ls.data = cds3.data;
}
ls.change.emit();
""")
There are no error message the callback is not implemented
You callback is never executed, because it is never added to the output. As soon as you call show the HTML output is generated and displayed. Anything after that point is effectively a no-op, and does not exist as far as the output is concerned. Typically show should be called last.
I'm using Holoviews and Bokeh and have an issue.
Using Bokeh I can specify the sizing_mode="scale_width" property, so my charts will be responsive.
And it works fine now.
But I couldn't find anything like this for Hovowiews.
boxwhisker = hv.BoxWhisker(df, ['cyl', 'origin'], 'mpg', label='')
boxwhisker.options(show_legend=False, height=200, sizing_mode='scale_width')
renderer = hv.renderer('bokeh')
boxChart = renderer.get_plot(boxwhisker).state
boxChart.name = 'boxChart'
curdoc().add_root(boxChart)
sizing_mode='scale_width' is second line is not working, so I have my chart size fixed, not responsive.
Is the any solution for it?
As of now you cannot do that directly via Holoviews, but there is a way through extracting a Bokeh plot from a Holoviews one. The idea is taken from this Holoviews page under 'Combining HoloViews and Bokeh Plots/Widgets'.
The above example could be made responsive as follows:
import holoviews as hv
import pandas as pd
from bokeh.io import curdoc
from bokeh.layouts import layout
hv.extension('bokeh')
data = [[1, 'A', 5],
[1, 'A', 3],
[1, 'B', 10],
[1, 'B', 5],
[2, 'A', 5],
[2, 'A', 19],
[2, 'B', 7],
[2, 'B', 10]]
df = pd.DataFrame.from_records(data, columns=['cyl', 'origin', 'mpg'])
boxwhisker = hv.BoxWhisker(df, ['cyl', 'origin'], 'mpg', label='')
boxwhisker.options(show_legend=False, height=200)
renderer = hv.renderer('bokeh').instance(mode='server')
doc = curdoc()
box_chart = renderer.get_plot(boxwhisker, doc)
doc.name = 'boxChart'
plot_layout = layout(box_chart.state, sizing_mode='scale_width')
doc.add_root(plot_layout)
From the bokeh examples
from bokeh.charts import HeatMap, output_file, show
data = {'fruit': ['apples']*3 + ['bananas']*3 + ['pears']*3,
'fruit_count': [4, 5, 8, 1, 2, 4, 6, 5, 4],
'sample': [1, 2, 3]*3}
hm = HeatMap(data, x='fruit', y='sample', values='fruit_count',
title='Fruits', stat=None)
show(hm)
is there a workaround for changing the order in which the labels are displayed? For example, if I wanted to show pears first?
First, you should not use bokeh.charts. It was deprecated, and has been removed from core Bokeh to a separate bkcharts repo. It is completely unsupported and unmaintained. It will not see any new features, bugfixes, improvements, or documentation. It is a dead end.
There are two good options to create this chart:
1) Use the stable and well-supported bokeh.plotting API. This is slightly more verbose, but gives you explicit control over everything, e.g. the order if the categories. In the code below these are specified as x_range and y_range values to figure:
from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource, LinearColorMapper
from bokeh.palettes import Spectral9
from bokeh.plotting import figure
from bokeh.transform import transform
source = ColumnDataSource(data={
'fruit': ['apples']*3 + ['bananas']*3 + ['pears']*3,
'fruit_count': [4, 5, 8, 1, 2, 4, 6, 5, 4],
'sample': ['1', '2', '3']*3,
})
mapper = LinearColorMapper(palette=Spectral9, low=0, high=8)
p = figure(x_range=['apples', 'bananas', 'pears'], y_range=['1', '2', '3'],
title='Fruits')
p.rect(x='fruit', y='sample', width=1, height=1, line_color=None,
fill_color=transform('fruit_count', mapper), source=source)
show(p)
This yields the output below:
You can find much more information (as well as live examples) about categorical data with Bokeh in the Handling Categorical Data sections of the User's Guide.
2) Look into HoloViews, which is a very high level API on top of Bokeh that is actively maintained by a team, and endorsed by the Bokeh team as well. A simple HeatMap in HoloViews is typically a one-liner as with bokeh.charts.
I'm learning Bokeh and ran the following example:
from bokeh.charts import HeatMap, output_file, show
import pandas as pd
output_file('heatmap.html')
df = pd.DataFrame(
dict(
apples=[4, 5, 8],
bananas=[1, 2, 4],
pears=[6, 5, 4],
),
index=['2012', '2013', '2014']
)
p = HeatMap(df, title='Fruits')
show(p)
It does not match what it is supposed to be:
http://docs.bokeh.org/en/0.9.3/docs/user_guide/charts.html#heatmap
Anybody have any ideas to fix the color? Thanks!
Here is an example. No matter what I can bar_width too, the figure looks exactly the same. How can I increase the widths of all the bars?
from bokeh.charts import Bar, output_notebook, show, vplot, hplot, defaults
from bokeh.sampledata.autompg import autompg as df
output_notebook()
df['neg_mpg'] = 0 - df['mpg']
defaults.width = 550
defaults.height = 400
bar_plot7 = Bar(df, label='cyl', values='displ', agg='mean', group='origin', bar_width=10,
title="label='cyl' values='displ' agg='mean' group='origin'", legend='top_right')
show(bar_plot7)
Looks like a bug in the new version of Bokeh where the widths are not making it all the way to the end. For now, you can do something like:
for r in bar_plot7.renderers:
try:
r.glyph.width = 0.1
except AttributeError:
pass
before the show() call to make skinny bars.
from bokeh.charts import Bar
from bokeh.charts.attributes import ColorAttr, CatAttr
from bokeh.charts.builders.bar_builder import BarBuilder
# output_file('try_select.html')
data = pd.DataFrame({'labels':['b', 'a', 'd', 'c'], 'values': [1, 2, 3, 4]}, index=[1, 2, 3, 4])
plt = Bar(data, values='values',label=CatAttr(columns=['labels'], sort=False),color=ColorAttr(columns=['labels']))
output_notebook()
show(plt)
this will work if you modify the df to your groupby df.