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_cmap
与 multi_line
一起使用,根据某些分类列为每条单独的线赋予不同的颜色。事实上,如果您只是想使用 multi_line
绘制一条可以在浏览器中映射的单线, factor_cmap
也可以工作(您需要将线数据嵌套得更深一层,因为multi_line
期望 "list of lists")。
但是找出单行 Python 的单一颜色颜色并将其作为 color
传递可能更容易。
我无法理解如何将分类数据映射到散景中的颜色。 我创建了一个看起来像
的示例数据框 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_cmap
与 multi_line
一起使用,根据某些分类列为每条单独的线赋予不同的颜色。事实上,如果您只是想使用 multi_line
绘制一条可以在浏览器中映射的单线, factor_cmap
也可以工作(您需要将线数据嵌套得更深一层,因为multi_line
期望 "list of lists")。
但是找出单行 Python 的单一颜色颜色并将其作为 color
传递可能更容易。