使用分类变量定义散景散点图中的颜色和标记
Use of a categorical variable to define colors and markers in bokeh scatter plot
我有一个 pandas 数据框,其中包含两个数据列(为简单起见,我们称它们为 'x' 和 'y'),以及一个分类列(例如 'color'值 'red'、'green' 和 'blue')。现在我想使用 bokeh 生成具有不同标记符号的散点图('red'->'x'、'green'->'o' 和 'blue'-> 'triangle').
虽然我确实找到了一个解决方案,我手动提取了 'x' 和 'y' 值的相关部分,但我认为应该可以使用 "categorical" 在一个命令中执行此操作在散景中绘制。但是,文档主要考虑条形图,当我尝试在 ColumnDataSource 中使用 df.groupby('color') 的结果时,在散点图中绘制 'x' 和 'y'(带有源=source) 失败,因为未找到列名 'x' 和 'y'。
下面是一个示例代码来说明问题:
import pandas as pd
import bokeh.plotting as plt
df = pd.DataFrame(data=[[0., 0., 'red'], [1., 0., 'red'], [1., 1., 'green'],
[1., 2., 'blue'], [2., 1., 'blue']],
columns=['x', 'y', 'color'])
source = plt.ColumnDataSource(df.groupby('color'))
# source = plt.ColumnDataSource(df) -- this would work for colors
fig = plt.figure()
fig.scatter('x', 'y', color='color', source=source)
plt.show(fig)
此代码段显示了所需的最低限度。没有 groupby,color='color' 实际上有效,但在我的真实示例中,分类变量具有非颜色值。此外,如何根据要求指定多个符号?
更新:下面的原始答案仍然有效,但这种事情现在也可以通过颜色和标记映射变换更容易地完成:
from bokeh.plotting import figure, show
from bokeh.sampledata.iris import flowers
from bokeh.transform import factor_cmap, factor_mark
SPECIES = ['setosa', 'versicolor', 'virginica']
MARKERS = ['hex', 'circle_x', 'triangle']
p = figure(title = "Iris Morphology")
p.xaxis.axis_label = 'Petal Length'
p.yaxis.axis_label = 'Sepal Width'
p.scatter("petal_length", "sepal_width", source=flowers, legend_field="species", fill_alpha=0.4, size=12,
marker=factor_mark('species', MARKERS, SPECIES),
color=factor_cmap('species', 'Category10_3', SPECIES))
show(p)
原答案
将 GroupBy
传递给 CDS 对您没有帮助,因为这会创建 汇总数据 的 CDS,但您需要所有个人点。这是使用 CDSView
和 GroupFilter
完成您所要求的一种方法,如 Providing Data for Plots and Tables:
中所述
import pandas as pd
from bokeh.io import show
from bokeh.models import ColumnDataSource, CDSView, GroupFilter
from bokeh.plotting import figure
df = pd.DataFrame(data=[[0., 0., 'red'], [1., 0., 'red'], [1., 1., 'green'],
[1., 2., 'blue'], [2., 1., 'blue']],
columns=['x', 'y', 'color'])
source = ColumnDataSource(df)
# create views for the different groups
red = CDSView(source=source, filters=[GroupFilter(column_name='color', group='red')])
green = CDSView(source=source, filters=[GroupFilter(column_name='color', group='green')])
blue = CDSView(source=source, filters=[GroupFilter(column_name='color', group='blue')])
p = figure()
# use the views with different glyphs
p.circle('x', 'y', size=15, color='red', source=source, view=red)
p.square('x', 'y', size=15, color='green', source=source, view=green)
p.triangle('x', 'y', size=15, color='blue', source=source, view=blue)
show(p)
看起来似乎有一些非常简单和容易的改进可以减少代码量(例如,可能 source.group
方法来完成那些 CDSView
行做,或者可能是字形方法的参数来指定组)。我鼓励您提交 GitHub feature request issue 以进一步讨论。
我有一个 pandas 数据框,其中包含两个数据列(为简单起见,我们称它们为 'x' 和 'y'),以及一个分类列(例如 'color'值 'red'、'green' 和 'blue')。现在我想使用 bokeh 生成具有不同标记符号的散点图('red'->'x'、'green'->'o' 和 'blue'-> 'triangle').
虽然我确实找到了一个解决方案,我手动提取了 'x' 和 'y' 值的相关部分,但我认为应该可以使用 "categorical" 在一个命令中执行此操作在散景中绘制。但是,文档主要考虑条形图,当我尝试在 ColumnDataSource 中使用 df.groupby('color') 的结果时,在散点图中绘制 'x' 和 'y'(带有源=source) 失败,因为未找到列名 'x' 和 'y'。
下面是一个示例代码来说明问题:
import pandas as pd
import bokeh.plotting as plt
df = pd.DataFrame(data=[[0., 0., 'red'], [1., 0., 'red'], [1., 1., 'green'],
[1., 2., 'blue'], [2., 1., 'blue']],
columns=['x', 'y', 'color'])
source = plt.ColumnDataSource(df.groupby('color'))
# source = plt.ColumnDataSource(df) -- this would work for colors
fig = plt.figure()
fig.scatter('x', 'y', color='color', source=source)
plt.show(fig)
此代码段显示了所需的最低限度。没有 groupby,color='color' 实际上有效,但在我的真实示例中,分类变量具有非颜色值。此外,如何根据要求指定多个符号?
更新:下面的原始答案仍然有效,但这种事情现在也可以通过颜色和标记映射变换更容易地完成:
from bokeh.plotting import figure, show
from bokeh.sampledata.iris import flowers
from bokeh.transform import factor_cmap, factor_mark
SPECIES = ['setosa', 'versicolor', 'virginica']
MARKERS = ['hex', 'circle_x', 'triangle']
p = figure(title = "Iris Morphology")
p.xaxis.axis_label = 'Petal Length'
p.yaxis.axis_label = 'Sepal Width'
p.scatter("petal_length", "sepal_width", source=flowers, legend_field="species", fill_alpha=0.4, size=12,
marker=factor_mark('species', MARKERS, SPECIES),
color=factor_cmap('species', 'Category10_3', SPECIES))
show(p)
原答案
将 GroupBy
传递给 CDS 对您没有帮助,因为这会创建 汇总数据 的 CDS,但您需要所有个人点。这是使用 CDSView
和 GroupFilter
完成您所要求的一种方法,如 Providing Data for Plots and Tables:
import pandas as pd
from bokeh.io import show
from bokeh.models import ColumnDataSource, CDSView, GroupFilter
from bokeh.plotting import figure
df = pd.DataFrame(data=[[0., 0., 'red'], [1., 0., 'red'], [1., 1., 'green'],
[1., 2., 'blue'], [2., 1., 'blue']],
columns=['x', 'y', 'color'])
source = ColumnDataSource(df)
# create views for the different groups
red = CDSView(source=source, filters=[GroupFilter(column_name='color', group='red')])
green = CDSView(source=source, filters=[GroupFilter(column_name='color', group='green')])
blue = CDSView(source=source, filters=[GroupFilter(column_name='color', group='blue')])
p = figure()
# use the views with different glyphs
p.circle('x', 'y', size=15, color='red', source=source, view=red)
p.square('x', 'y', size=15, color='green', source=source, view=green)
p.triangle('x', 'y', size=15, color='blue', source=source, view=blue)
show(p)
看起来似乎有一些非常简单和容易的改进可以减少代码量(例如,可能 source.group
方法来完成那些 CDSView
行做,或者可能是字形方法的参数来指定组)。我鼓励您提交 GitHub feature request issue 以进一步讨论。