如何在创建后更改matplotlib LineCollection的偏移量

1 投票
2 回答
2665 浏览
提问于 2025-04-16 19:57

我想用一个叫做 LineCollection 的东西来创建一堆线条图。下面的代码画出了两条相同的正弦曲线,它们之间的偏移量是 (0, 0.2):

import matplotlib.pyplot as plt
import matplotlib.collections
import numpy as np

x=np.arange(1000)
y=np.sin(x/50.)
l=zip(x,y)

f=plt.figure()
a=f.add_subplot(111)
lines=matplotlib.collections.LineCollection((l,l), offsets=(0,0.2))
a.add_collection(lines)
a.autoscale_view(True, True, True)
plt.show()

到这里一切都很好。不过问题是,我希望在创建之后能够调整这个偏移量。使用 set_offsets 这个方法似乎没有我想象中的效果。比如说,下面的代码对图表没有任何影响:

a.collections[0].set_offsets((0, 0.5))

顺便说一下,其他的一些设置命令(比如 set_color)都能按我预期的那样工作。那么,如何在曲线创建后改变它们之间的间距呢?

2 个回答

0

谢谢@matt的建议。根据这个建议,我简单拼凑了以下代码,它可以根据新的偏移值来移动曲线,同时也考虑了旧的偏移值。这意味着我不需要保留原始的曲线数据。类似的方法也许可以用来修正LineCollection的set_offsets方法,但我对这个类的细节了解得不够深,不敢轻易尝试。

def set_offsets(newoffsets, ax=None, c_num=0):
    '''
        Modifies the offsets between curves of a LineCollection

    '''

    if ax is None:
        ax=plt.gca()

    lcoll=ax.collections[c_num]
    oldoffsets=lcoll.get_offsets()

    if len(newoffsets)==1:
        newoffsets=[i*np.array(newoffsets[0]) for\
         (i,j) in enumerate(lcoll.get_paths())]
    if len(oldoffsets)==1:
        oldoffsets=[i*oldoffsets[0] for (i,j) in enumerate(newoffsets)]

    verts=[path.vertices for path in lcoll.get_paths()]

    for (oset, nset, vert) in zip(oldoffsets, newoffsets, verts):
        vert[:,0]+=(-oset[0]+nset[0])
        vert[:,1]+=(-oset[1]+nset[1])

    lcoll.set_offsets(newoffsets)
    lcoll.set_paths(verts)
1

我觉得你在使用matplotlib的时候发现了一个小问题,不过我有几个解决办法。看起来lines._paths是在LineCollection().__init__这个函数里根据你提供的偏移量生成的。当你调用lines.set_offsets()的时候,lines._paths并不会自动更新。在你简单的例子中,因为你还有原始数据,所以可以重新生成路径。

lines.set_offsets( (0., 0.2))
lines.set_segments( (l,l) )

你也可以手动调整你的偏移量。记住,你是在修改偏移点。所以如果你想要一个偏移量为0.2,你需要在原来的0.1的基础上再加0.1。

lines._paths[1].vertices[:,1] += 1

撰写回答