如何在单个图形中为不同的图获得不同的彩色线条?


202

matplotlib用来创建情节。我必须用不同的颜色来标识每个图,这些颜色应该由Python自动生成。

能否请您给我一种在同一图形中为不同图放置不同颜色的方法?

Answers:


424

Matplotlib默认情况下会执行此操作。

例如:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)
plt.show()

展示色彩循环的基本情节

而且,您可能已经知道,可以轻松添加图例:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)

plt.legend(['y = x', 'y = 2x', 'y = 3x', 'y = 4x'], loc='upper left')

plt.show()

带传说的基本情节

如果要控制将循环显示的颜色:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.gca().set_color_cycle(['red', 'green', 'blue', 'yellow'])

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)

plt.legend(['y = x', 'y = 2x', 'y = 3x', 'y = 4x'], loc='upper left')

plt.show()

该图显示了对默认颜色循环的控制

如果您不熟悉matplotlib,那么本教程是一个不错的起点

编辑:

首先,如果要在一个图形上绘制很多东西(> 5),则可以:

  1. 将它们放在不同的图上(考虑在一个图形上使用几个子图),或者
  2. 使用颜色以外的其他东西(即标记样式或线条粗细)来区分它们。

否则,您将面临一个非常混乱的情节!对要阅读您正在做的事情的人要好,不要试图将15种不同的东西塞成一个数字!

除此之外,许多人都存在不同程度的色盲现象,对于更多人来说,很难分辨出许多细微不同的颜色,这超出了您的想象。

话虽如此,如果您真的想在一条轴上放置20条线并使用20种相对不同的颜色,则可以采用以下一种方法:

import matplotlib.pyplot as plt
import numpy as np

num_plots = 20

# Have a look at the colormaps here and decide which one you'd like:
# http://matplotlib.org/1.2.1/examples/pylab_examples/show_colormaps.html
colormap = plt.cm.gist_ncar
plt.gca().set_prop_cycle(plt.cycler('color', plt.cm.jet(np.linspace(0, 1, num_plots))))

# Plot several different functions...
x = np.arange(10)
labels = []
for i in range(1, num_plots + 1):
    plt.plot(x, i * x + 5 * i)
    labels.append(r'$y = %ix + %i$' % (i, 5*i))

# I'm basically just demonstrating several different legend options here...
plt.legend(labels, ncol=4, loc='upper center', 
           bbox_to_anchor=[0.5, 1.1], 
           columnspacing=1.0, labelspacing=0.0,
           handletextpad=0.0, handlelength=1.5,
           fancybox=True, shadow=True)

plt.show()

基于给定颜色图的20条线的唯一颜色


17
请注意最后一个示例,在较新版本的matplotlib中,set_color_cycle不推荐使用,因此该行应为plt.gca().set_prop_cycle(plt.cycler('color', plt.cm.jet(np.linspace(0, 1, num_plots)))),只需更改plt.cm.YOUR_PREFERED_COLOR_MAP即可适合您的需求。
内特

1
@JoeKington:解释很棒,非常感谢
Rika

这很棒。有没有办法让他们互动?例如在RI中将ggplot转换为ggplotly(),该图变为html交互式
kRazzy R

我确信OP知道Matplotlib在单个绘图中(在一个图中)为不同的曲线适当地axes着色,并询问是否要在不同绘图中(不同的axes)改变单个线条的颜色。。。。问题(可能与OP提出的问题不同,但没人能告诉他们,因为他们问了这个问题,然后消失了!)— +1
gboffi

37

稍后设置

如果您不知道要绘制的图的数量,则可以在绘制颜色后直接使用来更改颜色,从而直接从图中检索编号.lines,我可以使用以下解决方案:

一些随机数据

import matplotlib.pyplot as plt
import numpy as np

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)


for i in range(1,15):
    ax1.plot(np.array([1,5])*i,label=i)

您需要的一段代码:

colormap = plt.cm.gist_ncar #nipy_spectral, Set1,Paired   
colors = [colormap(i) for i in np.linspace(0, 1,len(ax1.lines))]
for i,j in enumerate(ax1.lines):
    j.set_color(colors[i])
  

ax1.legend(loc=2)

结果如下:在此处输入图片说明


8

TL; DR不,它不能自动完成。是的,有可能。

import matplotlib.pyplot as plt
my_colors = plt.rcParams['axes.prop_cycle']() # <<< note that we CALL the prop_cycle
fig, axes = plt.subplots(2,3)
for ax in axes.flatten(): ax.plot((0,1), (0,1), **next(my_colors))

在此处输入图片说明 图(axes)中的每个图(figure)都有自己的颜色周期-如果您不为每个图强制使用不同的颜色,则所有图共享相同的颜色顺序,但是,如果我们稍微扩展一下“自动”的含义, 可以办到。


OP写道

[...]我必须用[Matplotlib]自动生成的不同颜色标识每个图。

但是... Matplotlib会为每条不同的曲线自动生成不同的颜色

In [10]: import numpy as np
    ...: import matplotlib.pyplot as plt

In [11]: plt.plot((0,1), (0,1), (1,2), (1,0));
Out[11]:

在此处输入图片说明

那么为什么要OP请求呢?如果我们继续阅读,我们有

能否请您给我一种在同一图形中为不同图放置不同颜色的方法?

这是有道理的,因为每个图(axes按Matplotlib的说法,每个图)都有自己的color_cycle(或更确切地说,在2018年,它是prop_cycle),并且每个图(axes)以相同的顺序重用相同的颜色。

In [12]: fig, axes = plt.subplots(2,3)

In [13]: for ax in axes.flatten():
    ...:     ax.plot((0,1), (0,1))

在此处输入图片说明

如果这是原始问题的意思,则一种可能性是为每个图明确命名不同的颜色。

如果绘图(经常发生)是在循环中生成的,我们必须有一个附加的循环变量来覆盖Matplotlib 自动选择的颜色。

In [14]: fig, axes = plt.subplots(2,3)

In [15]: for ax, short_color_name in zip(axes.flatten(), 'brgkyc'):
    ...:     ax.plot((0,1), (0,1), short_color_name)

在此处输入图片说明

另一种可能性是实例化循环器对象

from cycler import cycler
my_cycler = cycler('color', ['k', 'r']) * cycler('linewidth', [1., 1.5, 2.])
actual_cycler = my_cycler()

fig, axes = plt.subplots(2,3)
for ax in axes.flat:
    ax.plot((0,1), (0,1), **next(actual_cycler))

在此处输入图片说明

请注意,type(my_cycler)cycler.Cycler不过type(actual_cycler)itertools.cycle


3

我想对上一篇文章中给出的最后一个循环答案进行一些细微的改进(该文章是正确的,应该仍然可以接受)。标记最后一个示例时所做的隐式假设是,plt.label(LIST)将标记号X放入LIST与第X次相对应的行中plot。我以前在使用这种方法时遇到了问题。根据matplotlibs文档(http://matplotlib.org/users/legend_guide.html#adjusting-the-order-legend-item)构建图例并自定义标签的建议方法是使标签充满热情以及您认为它们所做的确切绘图:

...
# Plot several different functions...
labels = []
plotHandles = []
for i in range(1, num_plots + 1):
    x, = plt.plot(some x vector, some y vector) #need the ',' per ** below
    plotHandles.append(x)
    labels.append(some label)
plt.legend(plotHandles, labels, 'upper left',ncol=1)

**:Matplotlib图例不起作用


3
仅供参考:您也可以使用“标签” kwarg进行绘制,然后不带任何参数地调用图例。
乔·肯顿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.