Как определить линии графика в 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)))
Другие вопросы по тегам