Python Matplotlib 通过颜色图绘制带有颜色的线条
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38208700/
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
Matplotlib Plot Lines with Colors Through Colormap
提问by Scott
I am plotting multiple lines on a single plot and I want them to run through the spectrum of a colormap, not just the same 6 or 7 colors. The code is akin to this:
我在一个图上绘制多条线,我希望它们穿过颜色图的光谱,而不仅仅是相同的 6 或 7 种颜色。代码类似于:
for i in range(20):
for k in range(100):
y[k] = i*x[i]
plt.plot(x,y)
plt.show()
Both with colormap "jet" and another that I imported from seaborn, I get the same 7 colors repeated in the same order. I would like to be able to plot up to ~60 different lines, all with different colors.
使用颜色图“jet”和我从 seaborn 导入的另一个颜色图,我得到了以相同顺序重复的相同 7 种颜色。我希望能够绘制多达 60 条不同的线条,所有线条都具有不同的颜色。
回答by Bart
The Matplotlib colormaps accept an argument (0..1
, scalar or array) which you use to get colors from a colormap. For example:
Matplotlib 颜色图接受用于0..1
从颜色图中获取颜色的参数(、标量或数组)。例如:
col = pl.cm.jet([0.25,0.75])
Gives you an array with (two) RGBA colors:
为您提供一个具有(两种)RGBA 颜色的数组:
array([[ 0. , 0.50392157, 1. , 1. ], [ 1. , 0.58169935, 0. , 1. ]])
数组([[ 0. , 0.50392157, 1. , 1. ], [ 1. , 0.58169935, 0. , 1. ]])
You can use that to create N
different colors:
您可以使用它来创建N
不同的颜色:
import numpy as np
import matplotlib.pylab as pl
x = np.linspace(0, 2*np.pi, 64)
y = np.cos(x)
pl.figure()
pl.plot(x,y)
n = 20
colors = pl.cm.jet(np.linspace(0,1,n))
for i in range(n):
pl.plot(x, i*y, color=colors[i])
回答by Alex Williams
Bart's solution is nice and simple but has two shortcomings.
Bart 的解决方案很好也很简单,但有两个缺点。
plt.colorbar()
won't work in a nice way because the line plots aren't mappable (compared to, e.g., an image)It can be slow for large numbers of lines due to the for loop (though this is maybe not a problem for most applications?)
plt.colorbar()
不会以很好的方式工作,因为线图不可映射(与例如图像相比)由于 for 循环,大量行可能会很慢(尽管这对于大多数应用程序来说可能不是问题?)
These issues can be addressed by using LineCollection
. However, this isn't too user-friendly in my (humble) opinion. There is an open suggestion on GitHubfor adding a multicolor line plot function, similar to the plt.scatter(...)
function.
这些问题可以通过使用来解决LineCollection
。但是,在我(谦虚)看来,这对用户不太友好。GitHub 上有一个公开的建议添加多色线图功能,类似于该plt.scatter(...)
功能。
Here is a working example I was able to hack together
这是一个我能够一起破解的工作示例
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
def multiline(xs, ys, c, ax=None, **kwargs):
"""Plot lines with different colorings
Parameters
----------
xs : iterable container of x coordinates
ys : iterable container of y coordinates
c : iterable container of numbers mapped to colormap
ax (optional): Axes to plot on.
kwargs (optional): passed to LineCollection
Notes:
len(xs) == len(ys) == len(c) is the number of line segments
len(xs[i]) == len(ys[i]) is the number of points for each line (indexed by i)
Returns
-------
lc : LineCollection instance.
"""
# find axes
ax = plt.gca() if ax is None else ax
# create LineCollection
segments = [np.column_stack([x, y]) for x, y in zip(xs, ys)]
lc = LineCollection(segments, **kwargs)
# set coloring of line segments
# Note: I get an error if I pass c as a list here... not sure why.
lc.set_array(np.asarray(c))
# add lines to axes and rescale
# Note: adding a collection doesn't autoscalee xlim/ylim
ax.add_collection(lc)
ax.autoscale()
return lc
Here is a very simple example:
这是一个非常简单的例子:
xs = [[0, 1],
[0, 1, 2]]
ys = [[0, 0],
[1, 2, 1]]
c = [0, 1]
lc = multiline(xs, ys, c, cmap='bwr', lw=2)
Produces:
产生:
And something a little more sophisticated:
还有一些更复杂的东西:
n_lines = 30
x = np.arange(100)
yint = np.arange(0, n_lines*10, 10)
ys = np.array([x + b for b in yint])
xs = np.array([x for i in range(n_lines)]) # could also use np.tile
colors = np.arange(n_lines)
fig, ax = plt.subplots()
lc = multiline(xs, ys, yint, cmap='bwr', lw=2)
axcb = fig.colorbar(lc)
axcb.set_label('Y-intercept')
ax.set_title('Line Collection with mapped colors')
Produces:
产生:
Hope this helps!
希望这可以帮助!
回答by Ramon Crehuet
An anternative to Bart's answer, in which you do not specify the color in each call to plt.plot
is to define a new color cycle with set_prop_cycle
. His example can be translated into the following code (I've also changed the import of matplotlib to the recommended style):
Bart 的答案的一个替代方案,其中您没有在每次调用中指定颜色,plt.plot
而是使用 定义一个新的颜色循环set_prop_cycle
。他的例子可以翻译成下面的代码(我也把matplotlib的导入改成了推荐的样式):
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2*np.pi, 64)
y = np.cos(x)
n = 20
ax = plt.axes()
ax.set_prop_cycle('color',[plt.cm.jet(i) for i in np.linspace(0, 1, n)])
for i in range(n):
plt.plot(x, i*y)
回答by Shital Shah
If you are using continuous color pallets like brg, hsv, jet or the default one then you can do like this:
如果您使用的是 brg、hsv、jet 或默认的连续颜色托盘,那么您可以这样做:
color = plt.cm.hsv(r) # r is 0 to 1 inclusive
Now you can pass this color value to any API you want like this:
现在您可以将此颜色值传递给您想要的任何 API,如下所示:
line = matplotlib.lines.Line2D(xdata, ydata, color=color)