Итерация (или нет?) параметров для matplotlib для построения функции в Python

Подозреваю, что я до сих пор не совсем понимаю передачу аргументов (уже в моей предыдущей задаче: fmin (scipy) и понимание передачи параметров функции в Python)

Я придумал здесь упрощенную задачу и использовал итерацию, вдохновленный этим постом: Как использовать matplotlib для построения функции с аргументом на оси без использования другого n, потому что это не то, что мне нужно в моей функции.

import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline

dataset=[0.2,0.5,0.02,0.4,0.7]

def functie_f(x,lamb_da):
    return lamb_da*np.power((lamb_da*x),2)
print (functie_f(0.2,7))


def LogL(q):
    lamb_da = q
    return np.log(functie_f(dataset, lamb_da)).sum()

lamb_da=2
 
y=[functie_f(dataset,lamb_da) for i in dataset]
plt.plot(dataset,y)
print(y)

print (LogL(lamb_da))
#y2=[LogL(lamb_da) for j in dataset]
#plt.plot(dataset,y2)

что дает мне такой результат:

Итерация (или нет?) параметров для matplotlib для построения функции в Python

Отпечаток y показывает, что у меня есть 5 раз один и тот же массив и 5 раз константная функция для каждого отдельного массива. Я ожидал увидеть 1 функцию. Я думаю, что произошло то, что functie_f обрабатывает один и тот же набор данных несколько раз, но без итерации он также дает неправильное количество значений y (вот почему я попробовал итерацию, чтобы дать мне значение y для каждого значения x из набора данных.

Когда мне нужен и второй график (= тот же код, но последние две строки не закомментированы), это еще хуже, и мой первый график исчез.

вы можете увидеть это на этом изображении:

Итерация (или нет?) параметров для matplotlib для построения функции в Python

Поэтому я попытался пропустить итерацию, так как это дает мне слишком много массивов с одинаковыми значениями y, но когда я это делаю, у меня нет одинакового измерения для значений x и значений y.

Что я не понимаю и хотел бы исправить:

  1. Почему я получаю больше значений y, когда начинаю с того же набора данных?
  2. Могу ли я использовать разные параметры для функции и как? (например, кортеж и одно значение)
  3. Правильно ли передается мой параметр для графика LogL, использующего functie_f?

Вот мои попытки без итерации с одной и той же ошибкой для трех разных кодов:

Сначала я попытался просто исключить итерацию для y:


y=functie_f(dataset,lamb_da)
plt.plot(dataset,y)

Затем я попытался перебрать x (думая, что на каждое 1 значение x потребуется 1 значение y)

for x in dataset
    y=functie_f(dataset,lamb_da)
    plt.plot(dataset,y)

И я попытался написать это под объявлением y, потому что, возможно, в его функции также есть набор данных x, но это ничего не изменило (я также попробовал «обновить ядро, чтобы заставить его перезапустить код»)

 y=functie_f(dataset,lamb_da)
 for x in dataset
     plt.plot(dataset,y)

Для всех трех изменений выше я получаю (то же самое) следующее сообщение об ошибке:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-347b473a5e13> in <module>
     19 y=functie_f(dataset,lamb_da)
     20 for x in dataset:
---> 21     plt.plot(dataset,y)
     22 print(y)
     23 

/home/marecage/snap/jupyter/common/lib/python3.7/site-packages/matplotlib/pyplot.py in plot(scalex, scaley, data, *args, **kwargs)
   2767     return gca().plot(
   2768         *args, scalex=scalex, scaley=scaley,
-> 2769         **({"data": data} if data is not None else {}), **kwargs)
   2770 
   2771 

/home/marecage/snap/jupyter/common/lib/python3.7/site-packages/matplotlib/axes/_axes.py in plot(self, scalex, scaley, data, *args, **kwargs)
   1633         """
   1634         kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
-> 1635         lines = [*self._get_lines(*args, data=data, **kwargs)]
   1636         for line in lines:
   1637             self.add_line(line)

/home/marecage/snap/jupyter/common/lib/python3.7/site-packages/matplotlib/axes/_base.py in __call__(self, data, *args, **kwargs)
    310                 this += args[0],
    311                 args = args[1:]
--> 312             yield from self._plot_args(this, kwargs)
    313 
    314     def get_next_color(self):

/home/marecage/snap/jupyter/common/lib/python3.7/site-packages/matplotlib/axes/_base.py in _plot_args(self, tup, kwargs, return_kwargs)
    496 
    497         if x.shape[0] != y.shape[0]:
--> 498             raise ValueError(f"x and y must have same first dimension, but "
    499                              f"have shapes {x.shape} and {y.shape}")
    500         if x.ndim > 2 or y.ndim > 2:

ValueError: x and y must have same first dimension, but have shapes (5,) and (10,)

🤔 А знаете ли вы, что...
Python активно используется в научных и инженерных вычислениях.


53
1

Ответ:

Решено

Когда dataset — обычный список Python, lamb_da*x — это список, умноженный на целое число, что просто дублирует список x раз. Например:

a = [1, 2, 3]
b = 2
c = a*b
print(c)  # [1, 2, 3, 1, 2, 3]

В этой строке вы также выполняете понимание списка:

y = [functie_f(dataset,lamb_da) for i in dataset]

Здесь вы каждый раз вызываете функцию одинаково, поэтому получаете len(dataset) одинаковые результаты.

Вы можете исправить это одним из двух способов.

  1. Вы можете сохранить понимание списка, но фактически перебирать набор данных.
import numpy as np
import matplotlib.pyplot as plt

def functie_f(x, lamb_da):
    return lamb_da*np.power((lamb_da*x), 2)

lamb_da = 2
dataset = [0.2, 0.5, 0.02, 0.4, 0.7]

y = [functie_f(x, lamb_da) for x in dataset]
plt.plot(dataset, y)

Ваша ошибка во всех ваших циклах заключалась в том, что вы создавали нужную вам переменную (в разных случаях вы называли ее i или x), но на самом деле не использовали эти значения.

  1. Вы можете преобразовать dataset в массив numpy и удалить понимание списка.
import numpy as np
import matplotlib.pyplot as plt

def functie_f(x,lamb_da):
    return lamb_da*np.power((lamb_da*x),2)

lamb_da = 2
dataset = np.array([0.2,0.5,0.02,0.4,0.7])
 
y = functie_f(dataset, lamb_da)
plt.plot(dataset, y)

Оба метода дают такой результат:

Примечание: линия выглядит так (идущая вперед и назад), потому что ваши значения dataset не отсортированы.