Как нарисовать стрелки и прямоугольники (для структуры белка se c) вне основного графика в matplotlib? - PullRequest
3 голосов
/ 09 января 2020

Я пытаюсь нарисовать стрелки и прямоугольники в matplotlib (для представления вторичной структуры белка) рядом с осью Y графика, примерно так:

enter image description here

Начиная с здесь Я получил часть стрелки, но не могу понять, как нарисовать ее за пределами оси Y. Кроме того, есть ли способ рисовать прямоугольники в дополнение к стрелкам? Код и вывод ниже:

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
x_tail = 0.0
y_tail = -0.1
x_head = 0.0
y_head = 0.9
dx = x_head - x_tail
dy = y_head - y_tail
fig, axs = plt.subplots(nrows=2)
arrow = mpatches.FancyArrowPatch((x_tail, y_tail), (dx, dy),
                                 mutation_scale=50,
                                 transform=axs[0].transAxes)
axs[0].add_patch(arrow)

arrow = mpatches.FancyArrowPatch((x_tail, y_tail), (dx, dy),
                                 mutation_scale=100,
                                 transform=axs[1].transAxes)
axs[1].add_patch(arrow)
axs[1].set_xlim(0, 1)
axs[1].set_ylim(0, 1)

enter image description here

1 Ответ

1 голос
/ 10 января 2020

Похоже, оригинальный подход несколько сбивает с толку.

Хотя вы можете рисовать прямоугольники с помощью mpatch.Rectangle, я думаю, что проще также рисовать прямоугольники с помощью FancyArrowPatch. Это заставляет их вести себя и масштабироваться одинаково, что интересно для настройки ширины. Точно так же вертикальная линия также рисуется с помощью FancyArrowPatch.

. Для позиционирования кажется вы можете просто указать (tail_x, tail_y) и head_x, head_y. С помощью arrowstyle= можно установить визуальные размеры. Если исключить head_length= из стиля, кажется, что стрелка выглядит как прямоугольник. Для окраски есть facecolor= и edgecolor=. А также color=, который обрабатывает facecolor и edgecolor одновременно.

arrow1.set_clip_on(False) позволяет рисовать стрелки на полях. Другие функции могут иметь параметр clip_on=False. zorder= необходимо, чтобы сделать правильные линии видимыми, когда одна рисуется поверх другой.

Вот пример кода. Прямоугольник рисуется дважды, поэтому вертикальная линия не видна через штриховку. Теперь x определен в 'координатах оси' , а y в стандартных координатах данных. Координаты «оси» go от 0, левая граница, где обычно ось Y отрисовывается до 1, правая граница. Установка x в -0.1 означает 10% слева от оси Y.

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.transforms as mtransforms

x0 = -0.1

arrow_style="simple,head_length=15,head_width=30,tail_width=10"
rect_style="simple,tail_width=25"
line_style="simple,tail_width=1"

fig, ax = plt.subplots()

# the x coords of this transformation are axes, and the y coord are data
trans = mtransforms.blended_transform_factory(ax.transAxes, ax.transData)

y_tail = 5
y_head = 15
arrow1 = mpatches.FancyArrowPatch((x0, y_tail), (x0, y_head), arrowstyle=arrow_style, transform=trans)
arrow1.set_clip_on(False)
ax.add_patch(arrow1)

y_tail = 40
y_head = 60
arrow2 = mpatches.FancyArrowPatch((x0, y_tail), (x0, y_head), arrowstyle=arrow_style, facecolor='gold', edgecolor='black', linewidth=1, transform=trans)
arrow2.set_clip_on(False)
ax.add_patch(arrow2)

y_tail = 20
y_head = 40
rect_backgr = mpatches.FancyArrowPatch((x0, y_tail), (x0, y_head), arrowstyle=rect_style, color='white', zorder=0, transform=trans)
rect_backgr.set_clip_on(False)
rect = mpatches.FancyArrowPatch((x0, y_tail), (x0, y_head), arrowstyle=rect_style, fill=False, color='orange', hatch='///', transform=trans)
rect.set_clip_on(False)
ax.add_patch(rect_backgr)
ax.add_patch(rect)

line = mpatches.FancyArrowPatch((x0, 0), (x0, 80), arrowstyle=line_style, color='orange', transform=trans, zorder=-1)
line.set_clip_on(False)
ax.add_patch(line)

ax.set_xlim(0, 30)
ax.set_ylim(0, 80)
plt.show()

example plot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...