Добавление произвольной строки в график matplotlib в записной книжке ipython
Я новичок в python/matplotlib и использую его через ноутбук ipython. Я пытаюсь добавить некоторые строки аннотации к существующему графу, и я не могу понять, как визуализировать линии на графике. Так, например, если я рисую следующее:
import numpy as np
np.random.seed(5)
x = arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
p = plot(x, y, "o")
Я получаю следующий график:
![beautiful scatter plot]()
Итак, как бы добавить вертикальную линию от (70 100) до (70 250)? Как насчет диагональной линии от (70,100) до (90,200)?
Я пробовал несколько вещей с Line2D()
, что приводило к путанице с моей стороны. В R
я бы просто использовал функцию segment(), которая добавила бы сегменты линии. Существует ли эквивалент в matplotlib
?
Ответы
Ответ 1
Вы можете напрямую строить линии, которые вы хотите, подавая команду plot
с соответствующими данными (границами сегментов):
plot([x1, x2], [y1, y2], color='k', linestyle='-', linewidth=2)
(конечно, вы можете выбрать цвет, ширину линии, стиль линии и т.д.)
В вашем примере:
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(5)
x = np.arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
plt.plot(x, y, "o")
# draw vertical line from (70,100) to (70, 250)
plt.plot([70, 70], [100, 250], 'k-', lw=2)
# draw diagonal line from (70, 90) to (90, 200)
plt.plot([70, 90], [90, 200], 'k-')
plt.show()
![new chart]()
Ответ 2
Еще не поздно для новичков.
plt.axvline(x, color='r')
Он также принимает диапазон y, используя ymin и ymax.
Ответ 3
Использование vlines
:
import numpy as np
np.random.seed(5)
x = arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
p = plot(x, y, "o")
vlines(70,100,250)
Основные сигнатуры вызова:
vlines(x, ymin, ymax)
hlines(y, xmin, xmax)
Ответ 4
Matplolib теперь позволяет использовать "строки аннотаций" в соответствии с поиском OP. Функция annotate()
допускает несколько форм соединительных путей, и одной из них является безголовая стрелка и стрелка без хвоста, то есть простая линия.
ax.annotate("",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
arrowprops=dict(arrowstyle="-",
connectionstyle="arc3, rad=0"),
)
В документации говорится, что вы можете нарисовать только стрелку с пустой строкой в качестве первого аргумента.
Из примера OP:
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(5)
x = np.arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
plt.plot(x, y, "o")
# draw vertical line from (70,100) to (70, 250)
plt.annotate("",
xy=(70, 100), xycoords='data',
xytext=(70, 250), textcoords='data',
arrowprops=dict(arrowstyle="-",
connectionstyle="arc3,rad=0."),
)
# draw diagonal line from (70, 90) to (90, 200)
plt.annotate("",
xy=(70, 90), xycoords='data',
xytext=(90, 200), textcoords='data',
arrowprops=dict(arrowstyle="-",
connectionstyle="arc3,rad=0."),
)
plt.show()
![Example inline image]()
Как и в подходе в ответе gcalmettes, вы можете выбрать цвет, ширину линии, стиль линии и т.д.
Вот изменение части кода, из-за которой одна из двух строк примера станет красной, более широкой и непрозрачной на 100%.
# draw vertical line from (70,100) to (70, 250)
plt.annotate("",
xy=(70, 100), xycoords='data',
xytext=(70, 250), textcoords='data',
arrowprops=dict(arrowstyle="-",
edgecolor = "red",
linewidth=5,
alpha=0.65,
connectionstyle="arc3,rad=0."),
)
Вы также можете добавить кривую к соединительной линии, отрегулировав connectionstyle
.
Ответ 5
Вместо того, чтобы злоупотреблять plot
или annotate
, что будет неэффективно для многих строк, вы можете использовать matplotlib.collections.LineCollection
:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
np.random.seed(5)
x = np.arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
plt.plot(x, y, "o")
# Takes list of lines, where each line is a sequence of coordinates
l1 = [(70, 100), (70, 250)]
l2 = [(70, 90), (90, 200)]
lc = LineCollection([l1, l2], color=["k","blue"], lw=2)
plt.gca().add_collection(lc)
plt.show()
![Figure with two lines plotted via LineCollection]()
Требуется список строк [l1, l2, ...]
, где каждая строка представляет собой последовательность из N координат (N может быть больше двух).
Доступны стандартные ключевые слова форматирования, принимающие либо одно значение, в этом случае значение применяется к каждой строке, либо последовательность M values
, в этом случае значение для i-й строки равно values[i % M]
.