Обычно в данных координатах указывается местоположение отметок, в координатах смещения — текст отметок. Подробнее об этом можно узнать в документации к функции annotate().
Стрелку между двумя точками (xy и xytext) можно нарисовать, указав параметр arrowprops. Чтобы нарисовать только стрелку, используйте пустую строку в качестве первого параметра.
ax.annotate("",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3"),
)
Создание пути между двумя точками происходит в несколько этапов:
Соединение между двумя точками может быть создано с использованием одного из следующих стилей:
Стиль | Атрибуты |
---|---|
angle | angleA=90,angleB=0,rad=0.0 |
angle3 | angleA=90,angleB=0 |
arc | angleA=0,angleB=0,armA=None,armB=None,rad=0.0 |
arc3 | rad=0.0 |
bar | armA=0.0,armB=0.0,fraction=0.3,angle=None |
Обратите внимание, что «3» в названиях стилей angle3 и arc3 означает, что полученный путь представляет собой сегмент квадратичной кривой Безье (с тремя контрольными точками). Как будет обсуждаться ниже, когда путь соединения является сегментом квадратичной кривой, можно использовать некоторые опции стиля стрелок.
Поведение каждого стиля соединения демонстрируется в следующем примере (ограниченно). (Предупреждение: поведение стиля «bar» в настоящее время не определено и может измениться в будущем.)
Затем, согласно заданному стилю стрелки, путь соединения (после обрезки и сжатия) преобразуется в патч стрелки.
Стиль | Атрибуты |
---|---|
- | None |
-> | head_length=0.4,head_width=0.2 |
-[ | widthB=1.0,lengthB=0.2,angleB=None |
|-| | widthA=1.0,widthB=1.0 |
-|> | head_length=0.4,head_width=0.2 |
<- | head_length=0.4,head_width=0.2 |
<-> | head_length=0.4,head_width=0.2 |
<|- | head_length=0.4,head_width=0.2 |
< | -|> |
fancy | head_length=0.4,head_width=0.4,tail_width=0.4 |
simple | head_length=0.5,head_width=0.5,tail_width=0.2 |
wedge | tail_width=0.3,shrink_factor=0.5 |
Некоторые стили стрелок применимы только для создания путей соединения, состоящих из сегментов квадратичных кривых Безье. Это стили fancy, simple и wedge. Для этих стилей стрелок необходимо использовать стиль соединения angle3 или arc3.
Если предоставлена метка, патч patchA по умолчанию устанавливается как патч bbox метки.
Как и в команде text, вы можете использовать параметр bbox для рисования рамки вокруг текста.
По умолчанию начало координат устанавливается в центре диапазона текста. Вы можете настроить это с помощью ключевого слова relpos. Эти значения нормализованы относительно диапазона текста. Например, (0,0) обозначает нижний левый угол, а (1,1) — верхний правый угол.
Существует класс художников, которые можно разместить в привязках осей. Распространённым примером являются легенды. Этот тип художников можно создать с помощью класса OffsetBox. В mpl_toolkits.axes_grid.anchored_artists есть несколько предопределённых классов.
Например, следующий код создаёт художника с именем at, который размещает текст «Figure 1a» в позиции (2,0):
from mpl_toolkits.axes_grid.anchored_artists import AnchoredText
at = AnchoredText("Figure 1a",
prop=dict(size=8), frameon=True,
loc=2,
)
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at)
Ключевое слово loc имеет то же значение, что и в команде legend.
Одним из простых применений является случай, когда размер пикселя художника (или набора художников) известен при создании. Например, если вы хотите нарисовать круг фиксированного размера 20x20 пикселей (радиус 10 пикселей), вы можете использовать класс AnchoredDrawingArea. Экземпляр использует размеры области рисования для создания (в пикселях). Пользователи могут добавлять художников в область рисования по своему усмотрению. Обратите внимание, что диапазон добавленных художников не зависит от положения области рисования, а только от начального размера.
Добавление художников в область рисования не должно иметь преобразований (они будут перезаписаны), и размеры этих художников интерпретируются как координаты пикселей, т. е. радиусы кругов в приведённом выше примере равны 10 и 5 пикселей соответственно. Данный текст написан на языке Python.
Этот код похож на AnchoredDrawingArea
, за исключением того, что область художника при рисовании определяется указанным преобразованием.
from mpl_toolkits.axes_grid.anchored_artists import AnchoredAuxTransformBox
box = AnchoredAuxTransformBox(ax.transData, loc=2)
el = Ellipse((0, 0), width=0.1, height=0.4, angle=30) # в координатах данных!
box.drawing_area.add_artist(el)
Эллипс в примере имеет ширину и высоту, соответствующие 0,1 и 0,4 в координатах данных, и будет автоматически масштабироваться при изменении вида области осей.
В этом примере можно задать параметр bbox_to_anchor
. Используя HPacker
и VPacker
, вы можете расположить художников так же, как в примере.
Обратите внимание, что по умолчанию bbox_transform
установлен в IdentityTransform
.
Matplotlib поддерживает несколько типов координат для меток, описанных в тексте «Аннотирование текста» (см. ссылку). Для более продвинутых пользователей доступно несколько дополнительных опций:
Transform
, например:ax.annotate("Test", xy=(0.5, 0.5), xycoords=ax.transAxes)
Это эквивалентно:
ax.annotate("Test", xy=(0.5, 0.5), xycoords="axes fraction")
Используя его, вы можете пометить точку в другой области осей:
ax1, ax2 = subplot(121), subplot(122)
ax2.annotate("Test", xy=(0.5, 0.5), xycoords=ax1.transData,
xytext=(0.5, 0.5), textcoords=ax2.transData,
arrowprops=dict(arrowstyle="->"))
Artist
. Значения xy
(или xytext
) интерпретируются как дробные координаты прямоугольника Artist
(get_window_extent
возвращает значение).an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data",
va="center", ha="center",
bbox=dict(boxstyle="round", fc="w"))
an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, # (1,0.5) прямоугольника an1
xytext=(30, 0), textcoords="offset points",
va="center", ha="left",
bbox=dict(boxstyle="round", fc="w"),
arrowprops=dict(arrowstyle="->"))
Обратите внимание, что ваша задача — определить диапазон Artist
, к которому относится метка (в данном случае an1
), перед нанесением an2
. В большинстве случаев это означает, что an2
должен быть нанесён после an1
.
3. Вызываемый объект, который возвращает экземпляр BboxBase
или Transform
. Если возвращаемое значение является преобразованием, оно работает аналогично пункту 1, если возвращается bbox
, то аналогично пункту 2. Вызываемый объект должен принимать один параметр — экземпляр renderer
. Например, следующие две команды дают одинаковый результат:
an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1,
xytext=(30, 0), textcoords="offset points")
an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1.get_window_extent,
xytext=(30, 0), textcoords="offset points")
x
, второй — для y
. Например:annotate("Test", xy=(0.5, 1), xycoords=("data", "axes fraction"))
0,5 единицы измерения — это координаты данных, 1 единица измерения — нормализованные координаты области осей. Вы можете использовать Artist
или преобразование таким же образом. Например:
import matplotlib.pyplot as plt
plt.figure(figsize=(3, 2))
ax = plt.axes([0.1, 0.1, 0.8, 0.7])
an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data",
va="center", ha="center",
bbox=dict(boxstyle="round", fc="w"))
an2 = ax.annotate("Test 2", xy=(0.5, 1.), xycoords=an1,
xytext=(0.5, 1.1), textcoords=(an1, "axes fraction"),
va="bottom", ha="center",
bbox=dict(boxstyle="round", fc="w"),
arrowprops=dict(arrowstyle="->"))
plt.show()
OffsetFrom
помогает в таких случаях. Использование ConnectorPatch
ConnectorPatch похож на аннотацию без текста. Хотя в большинстве случаев рекомендуется использовать функции аннотирования, ConnectorPatch может быть полезен, когда вы хотите соединить точки на разных осях.
from matplotlib.patches import ConnectionPatch
xy = (0.2, 0.2)
con = ConnectionPatch(xyA=xy, xyB=xy, coordsA="data", coordsB="data",
axesA=ax1, axesB=ax2)
ax2.add_artist(con)
Приведённый выше код соединяет точку данных xy на ax1 с точкой данных xy на ax2. Это простой пример.
Хотя экземпляр ConnectorPatch можно добавить к любой оси, вам может потребоваться добавить его к самой последней оси в порядке построения, чтобы предотвратить перекрытие с другими осями.
Продвинутые темы
def __call__(self, x0, y0, width, height, mutation_size,
aspect_ratio=1.):
"""
Given the location and size of the box, return the path of
the box around it.
- *x0*, *y0*, *width*, *height* : location and size of the box
- *mutation_size* : a reference scale for the mutation.
- *aspect_ratio* : aspect-ratio for the mutation.
"""
path = ...
return path
Вот сложный пример:
Однако рекомендуется наследовать от matplotlib.patches.BoxStyle._Base и переопределить метод transmute.
from matplotlib.path import Path
from matplotlib.patches import BoxStyle
import matplotlib.pyplot as plt
# мы можем наследовать от класса matplotlib.patches.BoxStyle._Base.
# В этом случае вам нужно переопределить метод transmute.
class MyStyle(BoxStyle._Base):
"""
Простой прямоугольник.
"""
def __init__(self, pad=0.3):
"""
Аргументы должны быть числами с плавающей запятой и иметь
значения по умолчанию.
*pad*
количество отступов
"""
self.pad = pad
super(MyStyle, self).__init__()
def transmute(self, x0, y0, width, height, mutation_size):
"""
Учитывая местоположение и размер прямоугольника, верните путь
вокруг него.
- *x0*, *y0*, *width*, *height* : местоположение и размер коробки
- *mutation_size* : эталонный масштаб для мутации.
Часто *mutation_size* — это размер шрифта текста.
Вам не нужно беспокоиться о повороте, так как он автоматически учитывается.
"""
# отступ
pad = mutation_size * self.pad
# ширина и высота с добавленным отступом.
width, height = width + 2.*pad, \
height + 2.*pad,
# границы дополненной рамки
x0, y0 = x0-pad, y0-pad,
x1, y1 = x0+width, y0 + height
cp = [(x0, y0),
(x1, y0), (x1, y1), (x0, y1),
(x0-pad, (y0+y1)/2.), (x0, y0),
(x0, y0)]
com = [Path.MOVETO,
Path.LINETO, Path.LINETO, Path.LINETO,
Path.LINETO, Path.LINETO,
Path.CLOSEPOLY]
path = Path(cp, com)
return path
# зарегистрировать собственный стиль
BoxStyle._style_list["angled"] = MyStyle
plt.figure(1, figsize=(3,3))
ax = plt.subplot(111)
ax.text(0.5, 0.5, "Test", size=30, va="center", ha="center", rotation=30,
bbox=dict(boxstyle="angled,pad=0.5", alpha=0.2))
del BoxStyle._style_list["angled"]
plt.show()
Источник Аналогично можно определить собственный ConnectionStyle
и собственный ArrowStyle
.
Смотрите исходный код файла lib/matplotlib/patches.py, чтобы увидеть, как определяется каждый класс стилей.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )