Я хотел бы создать стек строк, используя 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))
BTW, другие команды набора (например, set_color
) работают так, как я ожидаю. Как изменить интервал между кривыми после их создания?
Я думаю, вы нашли ошибку в matplotlib, но у меня есть пара работ. Похоже, что lines._paths
генерируется в LineCollection().__init__
используя смещения, которые вы предоставляете. lines._paths
не lines._paths
свойства при вызове lines.set_offsets()
. В вашем простом примере вы можете повторно генерировать пути, поскольку у вас все еще есть оригиналы.
lines.set_offsets( (0., 0.2))
lines.set_segments( (l,l) )
Вы также можете вручную применить свои смещения. Помните, что вы изменяете точки смещения. Таким образом, чтобы получить смещение в 0.2, вы добавляете 0,1 к вашему ранее существующему смещению 0,1.
lines._paths[1].vertices[:,1] += 1
Спасибо @matt за ваше предложение. На основании этого я взломал вместе следующее, которое сдвигает кривые в соответствии с новыми значениями смещения, но учитывает старые значения смещения. Это означает, что мне не нужно сохранять исходные данные кривой. Что-то подобное может быть сделано для исправления метода set_offsets для LineCollection, но я не понимаю детали класса достаточно хорошо, чтобы рисковать.
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)