Как добавить линию на основе наклона и перехвата в Matplotlib?
В R есть функция abline
в которой линия может быть нарисована на графике на основе спецификации abline
(первый аргумент) и наклона (второй аргумент). Например,
plot(1:10, 1:10)
abline(0, 1)
где линия с пересечением 0 и наклоном 1 охватывает весь диапазон графика. Есть ли такая функция в Matplotlib?
Ответы
Ответ 1
Многие из этих решений сосредоточены на добавлении линии на график, который соответствует данным. Здесь простое решение для добавления произвольной линии к графику на основе наклона и пересечения.
import matplotlib.pyplot as plt
import numpy as np
def abline(slope, intercept):
"""Plot a line from slope and intercept"""
axes = plt.gca()
x_vals = np.array(axes.get_xlim())
y_vals = intercept + slope * x_vals
plt.plot(x_vals, y_vals, '--')
Ответ 2
Я знаю, что этот вопрос пару лет, но поскольку ответа нет, я добавлю, что работает для меня.
Вы можете просто построить значения в своем графике, а затем сгенерировать другой набор значений для координат линии наилучшего соответствия и построить график по вашему первоначальному графику. Например, см. Следующий код:
import matplotlib.pyplot as plt
import numpy as np
# Some dummy data
x = [1, 2, 3, 4, 5, 6, 7]
y = [1, 3, 3, 2, 5, 7, 9]
# Find the slope and intercept of the best fit line
slope, intercept = np.polyfit(x, y, 1)
# Create a list of values in the best fit line
abline_values = [slope * i + intercept for i in x]
# Plot the best fit line over the actual values
plt.plot(x, y, '--')
plt.plot(x, abline_values, 'b')
plt.title(slope)
plt.show()
Ответ 3
Я не мог понять, как это сделать, не прибегая к обратным вызовам, но это, похоже, работает достаточно хорошо.
import numpy as np
from matplotlib import pyplot as plt
class ABLine2D(plt.Line2D):
"""
Draw a line based on its slope and y-intercept. Additional arguments are
passed to the <matplotlib.lines.Line2D> constructor.
"""
def __init__(self, slope, intercept, *args, **kwargs):
# get current axes if user has not specified them
if not 'axes' in kwargs:
kwargs.update({'axes':plt.gca()})
ax = kwargs['axes']
# if unspecified, get the current line color from the axes
if not ('color' in kwargs or 'c' in kwargs):
kwargs.update({'color':ax._get_lines.color_cycle.next()})
# init the line, add it to the axes
super(ABLine2D, self).__init__([], [], *args, **kwargs)
self._slope = slope
self._intercept = intercept
ax.add_line(self)
# cache the renderer, draw the line for the first time
ax.figure.canvas.draw()
self._update_lim(None)
# connect to axis callbacks
self.axes.callbacks.connect('xlim_changed', self._update_lim)
self.axes.callbacks.connect('ylim_changed', self._update_lim)
def _update_lim(self, event):
""" called whenever axis x/y limits change """
x = np.array(self.axes.get_xbound())
y = (self._slope * x) + self._intercept
self.set_data(x, y)
self.axes.draw_artist(self)
Ответ 4
X = np.array([1, 2, 3, 4, 5, 6, 7])
Y = np.array([1.1,1.9,3.0,4.1,5.2,5.8,7])
scatter (X,Y)
slope, intercept = np.polyfit(X, Y, 1)
plot(X, X*slope + intercept, 'r')
Ответ 5
Я полагаю, что для случая (intercept, slope)
of (0, 1)
можно использовать и расширять следующую функцию для размещения других наклонов и перехватов, но не будет корректироваться, если изменения оси ограничены или автомасштабирование снова включено.
def abline():
gca = plt.gca()
gca.set_autoscale_on(False)
gca.plot(gca.get_xlim(),gca.get_ylim())
import matplotlib.pyplot as plt
plt.scatter(range(10),range(10))
abline()
plt.draw()
Ответ 6
Вот возможный обходной путь, который я x_intercept
: предположим, что мои координаты перехвата сохранены как x_intercept
и y_intercept
, а наклон (m) сохранен как my_slope
который был найден по известному уравнению m = (y2-y1)/(x2-x1) или каким-либо образом вам удалось найти его.
Используя другое известное общее уравнение для линии y = mx + q, я определяю функцию find_second_point
которая сначала вычисляет q (так как m, x и y известны), а затем вычисляет другую случайную точку, которая принадлежит этой линии.
Когда у меня есть две точки (начальная x_intercept
, y_intercept
и недавно найденный new_x
, new_y
), я просто new_y
сегмент через эти две точки. Вот код:
import numpy as np
import matplotlib.pyplot as plt
x_intercept = 3 # invented x coordinate
y_intercept = 2 # invented y coordinate
my_slope = 1 # invented slope value
def find_second_point(slope,x0,y0):
# this function returns a point which belongs to the line that has the slope
# inserted by the user and that intercepts the point (x0,y0) inserted by the user
q = y0 - (slope*x0) # calculate q
new_x = x0 + 10 # generate random x adding 10 to the intersect x coordinate
new_y = (slope*new_x) + q # calculate new y corresponding to random new_x created
return new_x, new_y # return x and y of new point that belongs to the line
# invoke function to calculate the new point
new_x, new_y = find_second_point(my_slope , x_intercept, y_intercept )
plt.figure(1) # create new figure
plt.plot((x_intercept, new_x),(y_intercept, new_y), c='r', label='Segment')
plt.scatter(x_intercept, y_intercept, c='b', linewidths=3, label='Intercept')
plt.scatter(new_x, new_y, c='g', linewidths=3, label='New Point')
plt.legend() # add legend to image
plt.show()
вот изображение, сгенерированное кодом:
![result image]()