使用Bokeh绘图时,如何自动循环使用颜色调色板?

34

我想使用循环来加载和/或修改数据,并在循环中使用Bokeh绘制结果(我熟悉Matplotlib的axes.color_cycle)。这是一个简单的例子。

import numpy as np
from bokeh.plotting import figure, output_file, show
output_file('bokeh_cycle_colors.html')

p = figure(width=400, height=400)
x = np.linspace(0, 10)

for m in xrange(10):
    y = m * x
    p.line(x, y, legend='m = {}'.format(m))

p.legend.location='top_left'
show(p)

生成此图的程序

bokeh plot

我如何使颜色循环,而不编写颜色列表和模数操作以在颜色数量用尽时重复?GitHub上有一些相关讨论,问题 351 2201,但是如何使其工作并不清楚。在搜索cycle color文档中,我得到了四个结果,但页面上实际上没有包含单词cycle

color cycler包是作为matplotlib的一部分开发的,它可能对创建一个字典循环使用不仅仅是颜色非常有用。 - Steven C. Howell
4个回答

40

最简单的方法可能是获取颜色列表并自行使用 itertools 进行循环:

import numpy as np
from bokeh.plotting import figure, output_file, show

# select a palette
from bokeh.palettes import Dark2_5 as palette
# itertools handles the cycling
import itertools  

output_file('bokeh_cycle_colors.html')

p = figure(width=400, height=400)
x = np.linspace(0, 10)

# create a color iterator
colors = itertools.cycle(palette)    

for m, color in zip(range(10), colors):
    y = m * x
    p.line(x, y, legend='m = {}'.format(m), color=color)

p.legend.location='top_left'
show(p)

在此输入图片描述


5
你可以创建一个迭代器,然后将 color=next(colors) 设置为跳过 zip - Tom Phillips

10
你可以定义一个简单的生成器来为你循环颜色。
在 Python 3 中:
from bokeh.palettes import Category10
import itertools

def color_gen():
    yield from itertools.cycle(Category10[10])
color = color_gen()

或者在Python 2(或3)中:

from bokeh.palettes import Category10
import itertools

def color_gen():
    for c in itertools.cycle(Category10[10]):
        yield c
color = color_gen()

当您需要一种新颜色时,请执行以下操作:

p.line(x, y1, line_width=2, color=color)
p.line(x, y2, line_width=2, color=color)

以下是上面的示例:

p = figure(width=400, height=400)
x = np.linspace(0, 10)

for m, c in zip(range(10), color):
    y = m * x
    p.line(x, y, legend='m = {}'.format(m), color=c)

p.legend.location='top_left'
show(p)

输入图像描述


6
color_gen 函数实际上只是 itertools.cycle 的包装器,没有实际作用。 - Elliot

7

只需进行两个小小的变更,之前的答案就能在Python 3中运行。

  • 修改为: for m, color in zip(range(10), colors):

  • 之前为:for m, color in itertools.izip(xrange(10), colors):


4

在 Python > 3.7 中,你可以像这样做:

from bokeh.palettes import Category10_10
       
color = Category10_10.__iter__()

p.line(x, y1, line_width=2, color=next(color))

每次使用next()函数时,它都会循环遍历列表中的每个元素,直到所有元素遍历完成。

在 Python 中,每种序列类型都可以返回一个迭代器对象。


3
这种方法有一个缺点,即迭代器不是循环的。调用 next() 方法第11次会引发异常。 - Karel Marik
非常正确,我只是提出了一个最小的例子,突出了序列类型中内置的迭代器对象。 - crowie
2
我认为 color = iter(Category10_10) 是更好的选择。 - NichtJens
同样的事情,但是是的,你说得对,它看起来更好。 - crowie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接