如何在单个图中为不同的绘图获取不同颜色的线条

232 投票
7 回答
459070 浏览
提问于 2025-04-16 10:39

我正在使用 matplotlib 来制作图表。我需要为每个图表指定不同的颜色,这些颜色应该由Python自动生成。

你能告诉我一个方法,让我在同一个图形中为不同的图表设置不同的颜色吗?

7 个回答

9

总结:不,这个事情不能自动完成。是的,确实可以做到。

import matplotlib.pyplot as plt
#                                    _____ VV______
my_colors = plt.rcParams['axes.prop_cycle']() 
# note that we CALLED the prop_cycle ‾‾‾‾‾‾ΛΛ‾‾‾‾‾‾

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

在这里输入图片描述


提问者写道:

[...] 我需要用不同的颜色来标识每个图,这些颜色应该是由[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]:

在这里输入图片描述

那么提问者为什么会这样问呢?如果我们继续往下看,就会发现:

你能给我一个方法,让同一个图里的不同图用不同的颜色吗?

这就有道理了,因为每个图(在Matplotlib里称为axes)都有自己的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

38

稍后设置颜色

如果你不知道要绘制多少个图形,你可以在绘制完之后再更改颜色。你可以通过使用 .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)

结果如下所示:在这里输入图片描述

468

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条线的独特颜色

撰写回答