Matplotlib-将颜色条添加到折线图序列


问题内容

对于变量z的许多不同值,我有两个变量(x,y)的折线图序列。我通常会添加带有以下图例的折线图:

import matplotlib.pyplot as plt

fig = plt.figure()
ax  = fig.add_subplot(111)
# suppose mydata is a list of tuples containing (xs, ys, z) 
# where xs and ys are lists of x's and y's and z is a number. 
legns = []
for(xs,ys,z) in mydata:
   pl = ax.plot(xs,ys,color = (z,0,0))
   legns.append("z = %f"%(z))
ax.legends(legns) 
plt.show()

但是我的图表太多,图例将覆盖该图表。我宁愿有一个颜色条来指示与该颜色相对应的z值。我在画廊中找不到任何类似的东西,而我的所有尝试都无法处理色标。显然,在尝试添加颜色条之前,必须创建一个绘图集合。

是否有捷径可寻?谢谢。

编辑(说明):

我想做这样的事情:

import matplotlib.pyplot as plt
import matplotlib.cm     as cm

fig = plt.figure()
ax  = fig.add_subplot(111)
mycmap = cm.hot
# suppose mydata is a list of tuples containing (xs, ys, z) 
# where xs and ys are lists of x's and y's and z is a number between 0 and 1
plots = []
for(xs,ys,z) in mydata:
   pl = ax.plot(xs,ys,color = mycmap(z))
   plots.append(pl)
fig.colorbar(plots)
plt.show()

但是,根据Matplotlib参考,这将不起作用,因为无论这意味着什么,绘图列表都不是“可映射的”。

我使用LineCollection以下方法创建了一个替代绘图功能:

def myplot(ax,xs,ys,zs, cmap):
    plot = lc([zip(x,y) for (x,y) in zip(xs,ys)], cmap = cmap)
    plot.set_array(array(zs))
    x0,x1 = amin(xs),amax(xs)
    y0,y1 = amin(ys),amax(ys)
    ax.add_collection(plot)
    ax.set_xlim(x0,x1)
    ax.set_ylim(y0,y1)
    return plot

xsys是x和y坐标的列表的列表和zs是条件的不同上色每行的列表。但是,这感觉有点像杂事……我认为会有更整齐的方法可以做到这一点。我喜欢该plt.plot()功能的灵活性。


问题答案:

(我知道这是一个老问题,但是…)色条需要使用matplotlib.cm.ScalarMappableplt.plot产生的线不是标量可映射的,因此,要制作色条,我们将需要使标量可映射。

好。因此,a的构造函数ScalarMappable需要一个cmap和一个norm实例。(规范将数据缩放到0-1范围,您已经使用过的cmap的值在​​0-1之间并返回一个颜色)。因此,在您的情况下:

import matplotlib.pyplot as plt
sm = plt.cm.ScalarMappable(cmap=my_cmap, norm=plt.normalize(min=0, max=1))
plt.colorbar(sm)

因为您的数据已经在0-1范围内,所以您可以将sm创建简化为:

sm = plt.cm.ScalarMappable(cmap=my_cmap)

希望能帮助到别人。

编辑 :对于matplotlib v1.2或更高版本,代码变为:

import matplotlib.pyplot as plt
sm = plt.cm.ScalarMappable(cmap=my_cmap, norm=plt.normalize(vmin=0, vmax=1))
# fake up the array of the scalar mappable. Urgh...
sm._A = []
plt.colorbar(sm)

编辑 :对于matplotlib v1.3或更高版本,代码变为:

import matplotlib.pyplot as plt
sm = plt.cm.ScalarMappable(cmap=my_cmap, norm=plt.Normalize(vmin=0, vmax=1))
# fake up the array of the scalar mappable. Urgh...
sm._A = []
plt.colorbar(sm)

编辑 :对于matplotlib v3.1或更高版本,简化为:

import matplotlib.pyplot as plt
sm = plt.cm.ScalarMappable(cmap=my_cmap, norm=plt.Normalize(vmin=0, vmax=1))
plt.colorbar(sm)