Bokeh:为什么 factor_cmap 在 vbar 中工作但不在行中?

Bokeh: Why does factor_cmap work in vbar but not in line?

我无法理解如何将分类数据映射到散景中的颜色。 我创建了一个看起来像

的示例数据框
                   A    B
2000-01-31  0.357440  baz
2000-02-29  0.377538  foo
2000-03-31  1.382338  bar
2000-04-30  1.175549  baz
2000-05-31 -0.939276  baz
2000-06-30 -1.143150  bar
2000-07-31 -0.542440  baz
2000-08-31 -0.548708  baz
2000-09-30  0.208520  bar
2000-10-31  0.212690  bar
2000-11-30  1.268021  foo
2000-12-31 -0.807303  bar
2001-01-31 -3.303072  bar
2001-02-28 -0.806650  baz
2001-03-31 -0.360329  baz

下面是一个(改编的)最小示例,其中使用了条形图并使用 factor_cmap:

自动选择颜色
from bokeh.models import ColumnDataSource
from bokeh.palettes import Dark2
from bokeh.plotting import figure, show
from bokeh.transform import factor_cmap
import numpy as np
import pandas.util.testing as pdt
import random

pdt.N, pdt.K = 15, 1  # Module-level default rows/columns
np.random.seed(444)

df = pdt.makeTimeDataFrame(freq='M')

#random.choices(['foo', 'bar', 'baz'], k=len(df))
df['B'] = random.choices(['foo', 'bar', 'baz'], k=df.index.size)

source = ColumnDataSource(df)

cmap = factor_cmap('B', Dark2[3], ['foo', 'bar', 'baz'])

p = figure(x_axis_type='datetime')
p.vbar(x='index', top='A', width=0.7, color=cmap, line_width=2, source=source)
show(p)

但是,如果我尝试用折线图做同样的事情

p = figure(x_axis_type='datetime')
p.line(x='index', y='A', color=cmap, line_width=2, source=source)
show(p)

我得到以下值错误

ValueError: expected an element of either Enum('aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen'), Regex('^#[0-9a-fA-F]{6}$'), Regex('^rgba\(((25[0-5]|2[0-4]\d|1\d{1,2}|\d\d?)\s*,\s*?){2}(25[0-5]|2[0-4]\d|1\d{1,2}|\d\d?)\s*,\s*([01]\.?\d*?)\)'), Regex('^rgb\(((25[0-5]|2[0-4]\d|1\d{1,2}|\d\d?)\s*,\s*?){2}(25[0-5]|2[0-4]\d|1\d{1,2}|\d\d?)\s*?\)'), Tuple(Byte(Int, 0, 255), Byte(Int, 0, 255), Byte(Int, 0, 255)), Tuple(Byte(Int, 0, 255), Byte(Int, 0, 255), Byte(Int, 0, 255), Percent) or RGB, got {'field': 'B', 'transform': CategoricalColorMapper(id='3465', ...)}

我哪里错了?

我可以通过在 'B' 的值上创建一个枢轴 table 并为每个值绘制一条线来解决这个问题。预期的输出将是这样的

但是,我需要手动指定每一个值和每一种颜色,每次唯一值发生变化时都会崩溃。

line 绘制一条直线,它在整个长度上始终只有一种颜色。没有什么可映射的,它只需要一条线的一种颜色。这是您尝试的方法不起作用的直接原因。

您可能会这样想:如果您的 CDS 有包含 10 个点的列并且您绘制了条形图,那么您将得到 10 个条形图,每个条形图可以有不同的颜色,对应于某些列中的 10 个值中的一个。但是将相同的数据传递给line,你只会得到一条线,它只有nine条线段(在10个点之间)。这与要映射到该列的 10 个因素不匹配,那么您到底希望那里发生什么?

如果您想绘制多条线,可以将 factor_cmapmulti_line 一起使用,根据某些分类列为每条单独的线赋予不同的颜色。事实上,如果您只是想使用 multi_line 绘制一条可以在浏览器中映射的单线, factor_cmap 也可以工作(您需要将线数据嵌套得更深一层,因为multi_line 期望 "list of lists")。

但是找出单行 Python 的单一颜色颜色并将其作为 color 传递可能更容易。