在matplotlib中使用gnuplot线条颜色变量?

7 投票
2 回答
3948 浏览
提问于 2025-04-17 10:43

我有一个包含y值的数组,这些y值形成了一条线。此外,我还有一个和y数组元素数量相同的数组,这个数组的值在0到1之间。我们把这个数组叫做'z'。我想把y值的数组绘制出来,让每个点的颜色和对应的z值相匹配。

在gnuplot中,你可以使用'lc variable'来实现这个效果:

plot ’data’ using 1:2:3 with points lc variable  

根据这里的建议:Matplotlib散点图;颜色作为第三个变量的函数,我能够使用散点图,这确实有效:

import matplotlib as mpl  
import matplotlib.pyplot as plt  

plt.scatter(x, y, c=z, s=1, edgecolors='none', cmap=mpl.cm.jet)  
plt.colorbar()  
plt.show()  

有没有办法在matplotlib的plot方法中做到这一点,类似于这个?

plt.plot(x, y, c=z)

当我尝试上面的代码时,所有的线条都变成了黑色。

2 个回答

19

我之前也遇到过同样的问题:我想画一些线条,颜色不一样,而且这个颜色是根据第三个变量(z)来决定的。

不过我确实想用线条,而不是像@joaquin的回答那样用标记点。我在一个matplotlib的示例中找到了一个解决方案,使用了一个叫做matplotlib.collections.LineCollection的类(链接在这里)。

下面是我的例子,它在一个Basemap上绘制轨迹,并根据高度给它们上色:

import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.collections import LineCollection
import numpy as np

m = Basemap(llcrnrlon=-42,llcrnrlat=0,urcrnrlon=5,urcrnrlat=50, resolution='h')
fig = plt.figure()
m.drawcoastlines()
m.drawcountries()

for i in trajectorias:
    # for each i, the x (longitude), y (latitude) and z (height)
    # are read from a file and stored as numpy arrays

    points = np.array([x, y]).T.reshape(-1, 1, 2)
    segments = np.concatenate([points[:-1], points[1:]], axis=1)

    lc = LineCollection(segments, cmap=plt.get_cmap('Spectral'),
                        norm=plt.Normalize(250, 1500))
    lc.set_array(z)
    lc.set_linewidth(2)

    plt.gca().add_collection(lc)

axcb = fig.colorbar(lc)
axcb.set_label('cota (m)')

plt.show()

高度依赖的轨迹

2

你可以使用散点图(scatter):

plt.scatter(range(len(y)), y, c=z, cmap=cm.hot)

这里是一个ipython -pylab的会话:

In [27]: z = [0.3,0.4,0.5,0.6,0.7,0.2,0.3,0.4,0.5,0.8,0.9]

In [28]: y = [3, 7, 5, 6, 4, 8, 3, 4, 5, 2, 9]

In [29]: plt.scatter(range(len(y)), y, s=60, c=z, cmap=cm.hot)
Out[29]: <matplotlib.collections.PathCollection at 0x9ec8400>

在这里输入图片描述

如果你想使用绘图(plot),你可以通过(pycrust会话)得到和上面一样的图:

>>> from matplotlib import pyplot as plt
>>> from matplotlib import cm
>>> y = [3,7,5,6,4,8,3,4,5,2,9]
>>> z = [0.3,0.4,0.5,0.6,0.7,0.2,0.3,0.4,0.5,0.8,0.9]
>>> for x, (v, c) in enumerate(zip(y,z)):
...      plt.plot(x,v,marker='o', color=cm.hot(c))
...      
[<matplotlib.lines.Line2D object at 0x0000000008C42518>]
[<matplotlib.lines.Line2D object at 0x0000000008C426D8>]
[<matplotlib.lines.Line2D object at 0x0000000008C42B38>]
[<matplotlib.lines.Line2D object at 0x0000000008C452B0>]
[<matplotlib.lines.Line2D object at 0x0000000008C45438>]
[<matplotlib.lines.Line2D object at 0x0000000008C45898>]
[<matplotlib.lines.Line2D object at 0x0000000008C45CF8>]
[<matplotlib.lines.Line2D object at 0x0000000008C48198>]
[<matplotlib.lines.Line2D object at 0x0000000008C485F8>]
[<matplotlib.lines.Line2D object at 0x0000000008C48A58>]
[<matplotlib.lines.Line2D object at 0x0000000008C4B1D0>]
>>> plt.show()
>>> 

撰写回答