Наложение стрелок расстояния в техническом чертеже
Я хочу указать расстояние на одном из моих участков. То, что я имею в виду, это то, как они делают это в технических чертежах, показывая двуглавую стрелку с расстоянием в виде текста рядом с ней.
Пример:
from matplotlib.pyplot import *
hlines(7,0,2, linestyles='dashed')
hlines(11,0,2, linestyles='dashed')
hlines(10,0,2, linestyles='dashed')
hlines(8,0,2, linestyles='dashed')
plot((1,1),(8,10), 'k',) # arrow line
plot((1,1),(8,8), 'k', marker='v',) # lower arrowhead
plot((1,1),(10,10), 'k', marker='^',) # upper arrowhead
text(1.1,9,"D=1")
В результате получается что-то вроде этого (два из hlines действительно не нужны, они просто увеличивают область рисования...): ![Distance marker manual style]()
Есть ли более быстрый способ сделать это, желательно с наконечниками стрелок, которые заканчиваются на точном месте, а не ниже/выше, где они должны быть?
Дополнительные пункты для автоматического размещения текста.
Edit:
Я играл с annotate
, но так как строка должна была быть принесена в жертву, это решение потеряло некоторые призывы ко мне. Спасибо, что указали на стрелочный стиль, но он не работал, когда я пытался что-то подобное.
Я думаю, что нет способа написать небольшую функцию, чтобы сделать это одним вызовом...
Ответы
Ответ 1
import matplotlib.pyplot as plt
plt.hlines(7, 0, 2, linestyles='dashed')
plt.hlines(11, 0, 2, linestyles='dashed')
plt.hlines(10, 0, 2, linestyles='dashed')
plt.hlines(8, 0, 2, linestyles='dashed')
plt.annotate(
'', xy=(1, 10), xycoords='data',
xytext=(1, 8), textcoords='data',
arrowprops={'arrowstyle': '<->'})
plt.annotate(
'D = 1', xy=(1, 9), xycoords='data',
xytext=(5, 0), textcoords='offset points')
# alternatively,
# plt.text(1.01, 9, 'D = 1')
plt.show()
дает
![enter image description here]()
Для получения дополнительной информации о многих параметрах, доступных с помощью plt.annotate
, см. эту страницу.
Как показано выше, текст можно поместить с помощью plt.annotate
или plt.text
. С помощью plt.annotate
вы можете указать смещение (например, (5, 0)
) в точках, тогда как plt.text
вы можете указать расположение текста в координатах данных (например, (1.01, 9)
).
Ответ 2
Попробуйте использовать annotate
:
annotate ('', (0.4, 0.2), (0.4, 0.8), arrowprops={'arrowstyle':'<->'})
![Image produced by annotate command]()
Я не уверен в автоматическом размещении текста.
Ответ 3
Я создал функцию, которая прекрасно справляется с этим:
import numpy as np
import matplotlib.pyplot as plt
def annotate_point_pair(ax, text, xy_start, xy_end, xycoords='data', text_offset=6, arrowprops = None):
"""
Annotates two points by connecting them with an arrow.
The annotation text is placed near the center of the arrow.
"""
if arrowprops is None:
arrowprops = dict(arrowstyle= '<->')
assert isinstance(text,str)
xy_text = ((xy_start[0] + xy_end[0])/2. , (xy_start[1] + xy_end[1])/2.)
arrow_vector = xy_end[0]-xy_start[0] + (xy_end[1] - xy_start[1]) * 1j
arrow_angle = np.angle(arrow_vector)
text_angle = arrow_angle - 0.5*np.pi
ax.annotate(
'', xy=xy_end, xycoords=xycoords,
xytext=xy_start, textcoords=xycoords,
arrowprops=arrowprops)
label = ax.annotate(
text,
xy=xy_text,
xycoords=xycoords,
xytext=(text_offset * np.cos(text_angle), text_offset * np.sin(text_angle)),
textcoords='offset points')
return label