Python, матплотлиб. Построить функцию между двумя точками - PullRequest
0 голосов
/ 22 февраля 2020

Я хочу построить функцию между 2 точками, используя matplotlib. Аналогичная проблема, но для случая 3d без рабочего ответа: Как построить функцию, ориентированную на локальную ось X Matplotlib 3D?

Я думаю, что это должно работать примерно так:

import matplotlib.pyplot as plt
import math

def foo(x, L):
    # some polynomial on [0, L]
    return x**2  # usually it's more difficult


def magic(plt, foo, point1, point2):
    """
    Plot foo from point1 to point2
    :param plt: matplotlib.pyplot
    :param foo: function
    :param point1: tuple (x1, y1) or list [x1, y1]
    :param point2: tuple (x2, y2) or list [x2, y2]
    :return:
    """
    # do magic
    # create modified function along new local x' axis using points in initial x,y axis?
    # create new axis, rotate and move them?
    pass

x1, y1 = 1, 1  # first point coordinates
x2, y2 = 2, 2  # second point coordinates
dx = x1 - x2
dy = y1 - y2
# length, this ratio is always True in my case (see picture below)
L = math.sqrt(dx * dx + dy * dy)

ax, fig = plt.subplots()
magic(plt, foo, (x1,y1), (x2, y2))
plt.show()

Важно: длина по новой оси не изменяется. Если на [0, L] есть функция, это означает, что она будет иметь тот же домен (или «длину») после поворота / перемещения или представления ее вдоль новой оси.

Вот изображение того, что я пытаюсь сделать

image

1 Ответ

0 голосов
/ 23 февраля 2020

Маги c не задействованы. Просто перевод из (0,0) в (x1, y1) и поворот на угол, определяемый dx и dy. Синус этого угла равен dy / L, а косинус dx / L. Использование numpy массивов удобно для написания функции - это краткая форма, а также ускорение вычислений.

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

import matplotlib.pyplot as plt
import numpy as np

def foo(x):
    # some function on [0, L]
    return np.sin(x*20)/(x+1)

def function_on_new_axis(foo, point1, point2):
    """
    Plot foo from point1 to point2
    :param foo: function
    :param point1: tuple (x1, y1) or list [x1, y1]
    :param point2: tuple (x2, y2) or list [x2, y2]
    :return:
    """
    # create modified function along new local x' axis using points in initial x,y axis?
    # create new axis, rotate and move them?
    dx = x2 - x1
    dy = y2 - y1
    L = np.sqrt(dx * dx + dy * dy)
    XI = np.linspace(0, L, 500)  # initial coordinate system
    YI = foo(XI)
    s =  dy  / L  # sine of the rotation angle
    c =  dx  / L  # cosine of the rotation angle
    XM = c * XI - s * YI + x1  # modified coordinate system
    YM = s * XI + c * YI + y1
    plt.plot(XI, YI, color='crimson', alpha=0.3)
    plt.plot(XM, YM, color='crimson')
    plt.plot([x1, x2], [y1, y2], 'go')

x1, y1 = 1, 1  # first point coordinates
x2, y2 = 2, 3  # second point coordinates


fig, ax = plt.subplots()
function_on_new_axis(foo, (x1,y1), (x2, y2))
ax.axis('equal')  # equal aspect ratio between x and y axis to prevent that the function would look skewed
# show the axes at (0,0)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
plt.show()

example plot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...