简体   繁体   中英

Color points in scatter plot of Bokeh

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?

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)

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)

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')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM