В matplotlib, как использовать вторичную ось, которая вводится в функцию вместе с первичной осью? - PullRequest
1 голос
/ 15 апреля 2020

У меня есть функция с двумя аргументами (x1, x2). Я хотел бы представить функцию с ее результатом на оси у, x1 на оси х и x2 на правой оси у (вторичная ось).

Моя проблема заключается в том, что значения Оси x1 и x2 не соответствуют друг другу точке функции.

Например:

Example chart

Я хочу, чтобы значение считывалось на первичном y ось, соответствующая входам x1 и x2 двух других осей.

Код:

x1 = np.linspace(0, 10, 10)
x2 = np.linspace(0, 5, 10)

f = lambda x1, x2: np.exp(-x1) / 10 + np.exp(-x2) / 10

resp = []
for i, j in zip(x1, x2):
    resp.append(f(i, j))
resp = np.array(resp)

fig, ax1 = plt.subplots()
ax2 = ax1.twinx()

ax1.plot(x1, resp)

ax1.set_xlabel('(x1)')
ax1.grid(True)
ax1.set_ylabel('(y)')

ax2.set_ylabel('(x2)')
ax2.set_yticks(x2)

plt.xticks(np.arange(min(x1), max(x1)))

plt.show()

1 Ответ

0 голосов
/ 16 апреля 2020

Если ваши входные аргументы находятся в состоянии блокировки, у вас нет функции двух аргументов. Функция двух аргументов имеет два независимых входа. Ваши входные данные зависимы, поэтому вместо записи f(x1, x2) у вас есть f(x, g(x)), то есть просто f'(x). В указанном примере c у вас есть x1 = np.linspace(0, 10, 10). Вместо того, чтобы писать x2 = np.linspace(0, 5, 10), вы можете просто написать x2 = 0.5 * x1. Ваша экспонента может быть записана как

x = np.linspace(0, 10, 10)
y = np.exp(-x) / 10 + np.exp(-x / 2) / 10

Обратите внимание, что вам не нужно определение функции или al oop для вычисления значений y. Использование al oop уничтожает всю цель использования numpy. Ваши исходные пять строк могли быть уменьшены до y = np.exp(-x1) / 10 + np.exp(-x2) / 10 таким же образом.

Теперь, если вы хотите увидеть вторичные значения x на графике y против x, вы можете взять страницу из учебников и сделайте что-то вроде:

fig, ax1 = plt.subplots()
ax1.plot(x, y)
ax1.set_xlabel('(x1)')
ax1.grid(True)
ax1.set_ylabel('(y)')

ax2 = ax1.secondary_xaxis('top', functions=(lambda x: x / 2, lambda x: 2 * x))
ax2.set_xlabel('(x2)')
plt.show()

Результат показывает "оба" ввода в слое:

enter image description here

Теперь, если вы действительно хотите иметь функцию двух переменных, то любая комбинация входных данных выдаст действительное значение y. В этом случае вам придется использовать функцию numpy, называемую broadcasting , которая сопоставляет размеры массива, выравнивая их справа.

Допустим, вы определили один из входных данных в качестве транспонирования:

x1 = np.linspace(0, 10, 10)                # Shape   (10,)
x2 = np.linspace(0, 5, 10).reshape(-1, 1)  # Shape (10, 1)

Результатом операции над этими значениями будет (10, 10) 2D-массив. Теперь вы можете осмысленно вычислять y как функцию двух независимых переменных:

y = np.exp(-x1) / 10 + np.exp(-x2) / 10

Чтобы построить такой массив, вам понадобятся две оси x и ось y, другими словами, трехмерный график. Вот один из способов отобразить что-то подобное в matplotlib:

from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm

fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
s = ax.plot_surface(x1, x2, y, cm=cm.jet)
ax.set_xlabel('(x1)')
ax.set_ylabel('(x2)')
ax.set_zlabel('(y)')
fig.colorbar(s)

Вот результирующий график:

enter image description here

Это до вас, какое представление функции вы хотите.

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