Python 如何在单个图中为不同的图获得不同的彩色线条?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4805048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get different colored lines for different plots in a single figure?
提问by pottigopi
I am using matplotlibto create the plots. I have to identify each plot with a different color which should be automatically generated by Python.
我正在matplotlib用来创建图。我必须用不同的颜色来标识每个图,这些颜色应该由 Python 自动生成。
Can you please give me a method to put different colors for different plots in the same figure?
你能给我一个方法,在同一个图中为不同的图放置不同的颜色吗?
回答by Joe Kington
Matplotlib does this by default.
Matplotlib 默认执行此操作。
E.g.:
例如:
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()


And, as you may already know, you can easily add a legend:
而且,您可能已经知道,您可以轻松添加图例:
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()


If you want to control the colors that will be cycled through:
如果要控制将循环的颜色:
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()


If you're unfamiliar with matplotlib, the tutorial is a good place to start.
如果您不熟悉 matplotlib,本教程是一个不错的起点。
Edit:
编辑:
First off, if you have a lot (>5) of things you want to plot on one figure, either:
首先,如果您想在一个图形上绘制很多(> 5)个东西,请执行以下任一操作:
- Put them on different plots (consider using a few subplots on one figure), or
- Use something other than color (i.e. marker styles or line thickness) to distinguish between them.
- 将它们放在不同的图上(考虑在一个图上使用几个子图),或
- 使用颜色以外的其他东西(即标记样式或线条粗细)来区分它们。
Otherwise, you're going to wind up with a verymessy plot! Be nice to who ever is going to read whatever you're doing and don't try to cram 15 different things onto one figure!!
否则,你会得到一个非常混乱的情节!无论你在做什么,都要善待那些会阅读的人,不要试图将 15 种不同的东西塞进一个人物!
Beyond that, many people are colorblind to varying degrees, and distinguishing between numerous subtly different colors is difficult for more people than you may realize.
除此之外,许多人都有不同程度的色盲,而且对于比你想象的更多的人来说,区分许多细微不同的颜色是很困难的。
That having been said, if you really want to put 20 lines on one axis with 20 relatively distinct colors, here's one way to do it:
话虽如此,如果您真的想在一个轴上放置 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()


回答by Tommy
I would like to offer a minor improvement on the last loop answer given in the previous post (that post is correct and should still be accepted). The implicit assumption made when labeling the last example is that plt.label(LIST)puts label number X in LISTwith the line corresponding to the Xth time plotwas called. I have run into problems with this approach before. The recommended way to build legends and customize their labels per matplotlibs documentation ( http://matplotlib.org/users/legend_guide.html#adjusting-the-order-of-legend-item) is to have a warm feeling that the labels go along with the exact plots you think they do:
我想对上一篇文章中给出的最后一个循环答案进行小幅改进(该文章是正确的,仍应被接受)。标记最后一个示例时所做的隐含假设是plt.label(LIST)将标签编号 X 放入LIST对应于第X次plot调用的行中。我以前遇到过这种方法的问题。根据 matplotlibs 文档(http://matplotlib.org/users/legend_guide.html#adjusting-the-order-of-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)
回答by G M
Setting them later
稍后设置它们
If you don't know the number of the plots you are going to plot you can change the colours once you have plotted them retrieving the number directly from the plot using .lines, I use this solution:
如果您不知道要绘制的图的数量,则可以在绘制它们后更改颜色.lines,使用直接从图中检索数字,我使用以下解决方案:
Some random data
一些随机数据
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)
The piece of code that you need:
您需要的代码段:
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)
回答by gboffi
TL;DRNo, it can't be done automatically. Yes, it is possible.
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))
Each plot (axes) in a figure (figure) has its own cycle of colors — if you don't force a different color for each plot, all the plots share the same order of colors but, if we stretcha bit what "automatically" means, it can be done.
图形 ( axes) 中的每个图 ( figure) 都有自己的颜色循环——如果您不为每个图强制使用不同的颜色,则所有图共享相同的颜色顺序,但是,如果我们稍微拉伸一下“自动”的含义, 可以办到。
The OP wrote
OP写道
[...] I have to identify each plot with a different color which should be automatically generated by [Matplotlib].
[...] 我必须用不同的颜色来标识每个图,这些颜色应该由 [Matplotlib] 自动生成。
But... Matplotlib automatically generates different colors for each different curve
但是... 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]:
So why the OP request? If we continue to read, we have
那么为什么要提出 OP 请求呢?如果我们继续阅读,我们有
Can you please give me a method to put different colors for different plots in the same figure?
你能给我一个方法,在同一个图中为不同的图放置不同的颜色吗?
and it make sense, because each plot (each axesin Matplotlib's parlance) has its own color_cycle(or rather, in 2018, its prop_cycle) and each plot (axes) reuses the same colors in the same order.
这是有道理的,因为每个图(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))
If this is the meaning of the original question, one possibility is to explicitly name a different color for each plot.
如果这是原始问题的含义,一种可能性是为每个图明确命名不同的颜色。
If the plots (as it often happens) are generated in a loop we must have an additional loop variable to override the color automaticallychosen by Matplotlib.
如果绘图(经常发生)是在循环中生成的,我们必须有一个额外的循环变量来覆盖由 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)
Another possibility is to instantiate a cycler object
另一种可能性是实例化一个循环器对象
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))
Note that type(my_cycler)is cycler.Cyclerbut type(actual_cycler)is itertools.cycle.
请注意,type(my_cycler)是cycler.Cycler但是type(actual_cycler)是itertools.cycle。

