I've used Bokeh to generate a multiline chart that updates using a slider. I cannot find a way to have each line drawn with a different colour. I've tried using itertools to iterate through a palette, and passing a range of palette colours.
Here's the itertools approach (full_source is there to support the slider interaction which uses CustomJS):
import itertools
from bokeh.plotting import figure
from bokeh.embed import components
from bokeh.models import CustomJS, ColumnDataSource, Slider
from bokeh.palettes import Category20 as palette
from bokeh.models.glyphs import MultiLine
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.layouts import column, row
from bokeh.io import show
data={'xdata':[[0, 1, 2, 4, 5, 6, 10, 11, 12], [4, 8, 16, 0, 13, 21, -3, 9, 21]],
'ydata':[[4, 8, 16, 0, 13, 21, -3, 9, 21], [0, 1, 2, 4, 5, 6, 10, 11, 12]]}
colors=itertools.cycle(palette[2])
source = ColumnDataSource(data)
full_source = ColumnDataSource(data)
glyph = MultiLine(xs='xdata', ys='ydata', line_color = next(colors))
p = figure(title = None, plot_width = 400, plot_height = 400, toolbar_location = None)
p.add_glyph(source, glyph)
print(glyph.line_color)
show(p)
This gives two lines, but both of the same colour. print(glyph.line_color)
shows just one color passed - #1f77b4 (which is the first colour in the Category20 palette)
I've also tried using the example found here:
import itertools
from bokeh.plotting import figure
from bokeh.embed import components
from bokeh.models import CustomJS, ColumnDataSource, Slider
from bokeh.palettes import Spectral11
from bokeh.models.glyphs import MultiLine
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.layouts import column, row
from bokeh.io import show
data={'xdata':[[0, 1, 2, 4, 5, 6, 10, 11, 12], [4, 8, 16, 0, 13, 21, -3, 9, 21]],
'ydata':[[4, 8, 16, 0, 13, 21, -3, 9, 21], [0, 1, 2, 4, 5, 6, 10, 11, 12]]}
my_pallet = Spectral11[0:2]
source = ColumnDataSource(data)
full_source = ColumnDataSource(data)
glyph = MultiLine(xs='xdata', ys='ydata', line_color = my_pallet)
p = figure(title = None, plot_width = 400, plot_height = 400, toolbar_location = None)
p.add_glyph(source, glyph)
print(glyph.line_color)
show(p)
This gives:
ValueError expected an element of either String, Dict(Enum('expr', 'field', 'value', 'transform'), Either(String, Instance(Transform), Instance(Expression), Color)) or Color, got ['#5e4fa2', '#3288bd', '#66c2a5']
How can I get multiple colours from a palette into a MultiLine graph?
Ok it looks like I'd not been using ColumnDataSource correctly. By passing the colours into the ColumnDataSource as an additional key:value pair in the data Dict, it works. I also could get rid of the MultiLine glyph object.
Working code is:
from bokeh.plotting import figure
from bokeh.embed import components
from bokeh.models import CustomJS, ColumnDataSource, Slider
from bokeh.palettes import Category20 as palette
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.layouts import column, row
from bokeh.io import show
data = {'xs':[[...,...,..,][...,...,...]],'ys':[[...,...,..,][...,...,...]]}
length = len(data)
colors = palette[length]
#because Category20 has a minimum of 3 values, and length may be smaller
while len(colors)>length:
colors.pop()
data['color'] = colors
source = ColumnDataSource(data)
full_source = ColumnDataSource(data)
p = figure(title = None, plot_width = 400, plot_height = 400, toolbar_location = None)
p.multi_line(xs='xs', ys='ys', source=source, line_color='color')