Как определить линии графика в matplotlib
У меня есть данные x, y для путей в следующем формате (образец только для иллюстрации):
seq p1 p2
0 20 2 3
1 20 2 4
2 20 4 4
3 22 5 5
4 22 5 6
5 23 6 2
6 23 6 3
7 23 6 4
Каждый путь имеет количество точек, и они идентифицируются последовательностью, точки, принадлежащие одному и тому же последовательности, рассматриваются как один путь и так далее.
Я составил эти пути (используя мои реальные данные в том же формате, что и выше), используя следующий код, а также приложил результат:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 8))
for (key, grp) in df.groupby("seq"):
grp.plot(linestyle = "solid", x="p1", y="p2", ax = ax, label = key)
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.title("Paths")
plt.show()
Я наметил около 40 путей, теперь проблема в том, как мне определить, какой путь для uid 184 или uid-194? Они оба помечены одинаковым цветом в легенде. Есть ли способ, которым я могу различить каждый путь по-разному, возможно, пометив где-нибудь на пути (но это может сделать загроможденный график).
Мой второй вопрос - я хочу отметить начальную и конечную точки каждого пути / траектории. Например, начальная точка может быть зеленой, а конечная точка может быть красной. Например, в приведенном выше примере df для uid-20 начальные точки (2,3) в строке 0 и конечные точки (4,4) в строке 2. Пожалуйста, предложите способ отметить эти начальные и конечные точки для каждый путь в DF.
1 ответ
Я не уверен, насколько это отвечает на ваш вопрос, но это способ сделать цвета линий совместимыми с цветовой картой, что обычно помогает мне легче визуализировать различные линии и их тренды, но может быть не очень удобно выделять одну линию,
cmap = plt.cm.get_cmap('viridis')
groups = df.groupby("uid")
ngroups = len(groups)
for i, (key, grp) in enumerate(groups):
grp.plot(linestyle="solid", x="px", y="py", ax=ax, label=key, color=cmap(i/(ngroups-1))
чтобы добавить маркеры для первой и последней точек, просто выделите их и назначьте цвет и маркер, которые вам нравятся. Итак, переписываем цикл for выше:
for i, (key, grp) in enumerate(df.groupby("uid")):
grp.plot(linestyle="solid", x="px", y="py", ax=ax, label=key, color=cmap(i/(ngroups-1)))
grp.iloc[[0]].plot(marker="o", x="px", y="py", ax=ax, color='r', legend=False)
grp.iloc[[-1]].plot(marker="o", x="px", y="py", ax=ax, color='g', legend=False)
если вы хотите, чтобы каждый маркер имел разные оттенки красного и зеленого, вы можете использовать Reds
а также Greens
карты цветов, такие как:
start_cmap = plt.cm.get_cmap('Reds')
end_cmap = plt.cm.get_cmap('Greens')
и в цикле это будет
grp.iloc[[0]].plot(marker="o", x="px", y="py", ax=ax, color=start_cmap(i/(ngroups-1)), legend=False)
grp.iloc[[-1]].plot(marker="o", x="px", y="py", ax=ax, color=end_cmap(i/(ngroups-1)), legend=False)
редактирует
Обработка Легенд
Чтобы построить только линии, а не маркеры конечных точек, мы используем тот факт, что сначала мы построили линию, а затем два маркера, и именно так графики помещаются в очередь линий оси, поэтому мы пропускаем маркеры и четко скажите легенде, какие строки следует учитывать:
ax.legend(ax.lines[::3], groups.groups.keys(), loc='center left', bbox_to_anchor=(1, 0.5))
Использование Colorbar
Если для линий используется цветовая карта, полезно отобразить цветную полосу, а не условные обозначения, поэтому мы используем что-то вроде этого:
from matplotlib.colorbar import ColorbarBase
import matplotlib as mp
values = list(groups.groups.keys())
cax = fig.add_axes([0.92, 0.12, 0.02, 0.75])
cbar = ColorbarBase(cax, cmap=cmap, format='%d', ticks=values, drawedges=False, norm=mp.colors.Normalize(vmin=min(values), vmax=max(values)))