Добавление произвольной линии для библиотек 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")

Я получаю следующий график:

так как бы я добавил вертикальную линию от (70,100) до (70,250)? Как насчет диагональной линии от (70,100) до (90,200)?

Я пробовал несколько вещей с Line2D() в результате ничего, кроме путаницы с моей стороны. В R Я бы просто использовал функцию segments (), которая добавила бы линейные сегменты. Есть ли эквивалент в matplotlib?

4 84

4 ответа:

вы можете непосредственно построить линии, которые вы хотите, подавая 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

для новичков еще не поздно.

plt.axvline(x, color='r')

http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.axvline

Он также принимает диапазон y, используя ymin и ymax.

используя 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)

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"),
            )

на документация он говорит, что вы можете нарисовать только стрелки с пустой строкой в качестве первого аргумента.

из примера ОП:

%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.