В принципе это примерно так:
Код: Выделить всё
import numpy as np
import matplotlib.patches as patches
import matplotlib.pyplot as plt
def test(bar_height=0.8, figsize=(10, 6), arrow_headlen=0.2, dpi=600):
X0 = np.arange(0, 10, 1)
X1 = X0 + 2
Y = np.arange(0, 10, 1)
fig = plt.figure(figsize=figsize)
ax = fig.add_subplot(111)
data_2_px = ax.transData.transform # data domain to figure
px_2_data = ax.transData.inverted().transform # figure to data domain
# get arrow head_length as fraction of arrow width
# so that it doesnt grow longer with longer x-axis
dy = bar_height * arrow_headlen
dpx = data_2_px([(0, dy)]) - data_2_px([(0, 0)])
arrowlen = (px_2_data([(dpx[0, 1], dpx[0, 0])]) - px_2_data([(0, 0)]))[0, 0]
ax.barh(y=Y, left=X0, width=X1 - X0, height=bar_height, color="0.5")
for y, x1 in zip(Y, X1):
yl = y - 0.49 * bar_height # low arrow corner (avoid being draw 1 px too low)
yh = y + 0.49 * bar_height # high arrow corner (avoid being draw 1 px too high)
arrow = patches.Polygon([(x1, yl), (x1, yh), (x1 + arrowlen, y)], color="0.5")
ax.add_patch(arrow)
# highlight parts of arrows
ax.barh(y=Y, left=X0 + 0.5, width=(X1 - X0) / 2, height=bar_height, color="blue")
fig.savefig("./test_from_savefig.png", dpi=dpi)
plt.show()
Когда plt.show() открывает это в Viewer, и я сохраняю его оттуда. Я получаю это изображение (A):

Изображение, сохраненное с помощью fig.savefig() с более высоким разрешением, однако дает это изображение (B):

Как вы можете видеть, наконечники стрелок внезапно не оказались на одном уровне с основанием стрелки больше.
Похоже, что они были масштабированы иначе, чем полосы.
Но они оба определены в области данных.
Так что, разве они не должны быть заподлицо.< /p>
Изображение A — это то, что я хочу создать:
- серые стрелки определенной ширины, ширина головки которых равна ширина основания стрелки
- наконечники стрелок не становятся длиннее или короче в зависимости от оси X
- возможность выделить часть основания стрелки
Почему я не использую FancyArrow?
Код: Выделить всё
FancyArrow
Однако они рисуются не очень воспроизводимо.
Иногда FancyArrow рисуется на 1 пиксель выше или ниже .
Это означает, что если я нарисую серую FancyArrow, а затем синий прямоугольник над ней, иногда будет наблюдаться некоторое видимое смещение (например, за синей линией видна серая линия толщиной 1 пиксель). область).
Я обнаружил, что только barh может нарисовать полосу разных цветов, которая на самом деле выглядит так, будто она принадлежит друг другу.
Подробнее здесь: https://stackoverflow.com/questions/791 ... matplotlib