Reputation: 13081
I have the following simple pandas.DataFrame
:
df = pd.DataFrame(
{
"journey": ['ch1', 'ch2', 'ch2', 'ch1'],
"cat": ['a', 'b', 'a', 'c'],
"kpi1": [1,2,3,4],
"kpi2": [4,3,2,1]
}
)
Which I plot as follows:
import bokeh.plotting as bpl
import bokeh.models as bmo
bpl.output_notebook()
source = bpl.ColumnDataSource.from_df(df)
hover = bmo.HoverTool(
tooltips=[
("index", "@index"),
('journey', '@journey'),
("Cat", '@cat')
]
)
p = bpl.figure(tools=[hover])
p.scatter(
'kpi1',
'kpi2', source=source)
bpl.show(p) # open a browser
I am failing to color code the dots according to the cat
. Ultimately, I want to have the first and third point in the same color, and the second and fourth in two more different colors.
How can I achieve this using Bokeh?
Upvotes: 7
Views: 19556
Reputation: 10604
Here's a way that avoids manual mapping to some extent. I recently stumbled on bokeh.palettes
at this github issue, as well as CategoricalColorMapper
in this issue. This approach combines them. See the full list of available palettes here and the CategoricalColorMapper
details here.
I had issues getting this to work directly on a pd.DataFrame
, and also found it didn't work using your from_df()
call. The docs show passing a DataFrame
directly, and that worked for me.
import pandas as pd
import bokeh.plotting as bpl
import bokeh.models as bmo
from bokeh.palettes import d3
bpl.output_notebook()
df = pd.DataFrame(
{
"journey": ['ch1', 'ch2', 'ch2', 'ch1'],
"cat": ['a', 'b', 'a', 'c'],
"kpi1": [1,2,3,4],
"kpi2": [4,3,2,1]
}
)
source = bpl.ColumnDataSource(df)
# use whatever palette you want...
palette = d3['Category10'][len(df['cat'].unique())]
color_map = bmo.CategoricalColorMapper(factors=df['cat'].unique(),
palette=palette)
# create figure and plot
p = bpl.figure()
p.scatter(x='kpi1', y='kpi2',
color={'field': 'cat', 'transform': color_map},
legend='cat', source=source)
bpl.show(p)
Upvotes: 18
Reputation: 13081
For the sake of completeness, here is the adapted code using low-level chart:
import pandas as pd
import bokeh.plotting as bpl
import bokeh.models as bmo
bpl.output_notebook()
df = pd.DataFrame(
{
"journey": ['ch1', 'ch2', 'ch2', 'ch1'],
"cat": ['a', 'b', 'a', 'c'],
"kpi1": [1,2,3,4],
"kpi2": [4,3,2,1],
"color": ['blue', 'red', 'blue', 'green']
}
)
df
source = bpl.ColumnDataSource.from_df(df)
hover = bmo.HoverTool(
tooltips=[
('journey', '@journey'),
("Cat", '@cat')
]
)
p = bpl.figure(tools=[hover])
p.scatter(
'kpi1',
'kpi2', source=source, color='color')
bpl.show(p)
Note that the colors are "hard-coded" into the data.
Here is the alternative using high-level chart:
import pandas as pd
import bokeh.plotting as bpl
import bokeh.charts as bch
bpl.output_notebook()
df = pd.DataFrame(
{
"journey": ['ch1', 'ch2', 'ch2', 'ch1'],
"cat": ['a', 'b', 'a', 'c'],
"kpi1": [1,2,3,4],
"kpi2": [4,3,2,1]
}
)
tooltips=[
('journey', '@journey'),
("Cat", '@cat')
]
scatter = bch.Scatter(df, x='kpi1', y='kpi2',
color='cat',
legend="top_right",
tooltips=tooltips
)
bch.show(scatter)
Upvotes: 2
Reputation: 7058
you could use the higher level Scatter
like here
or provide a color column to the ColumnDataSource
and reference it in your p.scatter(..., color='color_column_label')
Upvotes: -2