0

I suspect I still don't understand argument passing entirely (already in my previous problem: fmin (scipy) and understanding parameter passing of the function in python )

I made up a simplified problem here and used iteration, inspired by this post: How to use matplotlib to plot a function with the argument on an axis without using a different n cause that is not what I need in my function.

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)

which gives me this outcome:

first result

The print of y shows that I have 5 times the same array and 5 times a constant function for each different array. I expected to see 1 function. What I think has happened is that functie_f goes over the same dataset multiple times, but without the iteration it also gives a wrong number of y-values (that is why I tried the iteration to give me a y-value for each x-value from the dataset.

When I want the second plot as well (=same code but with the last two lines not commented out) it is worse, also my first plot has disapeared.

you can see that in this image:

second result

So I tried to omit the iteration since that gives me too many arrays with the same y-values, but when I do that I don't have the same dimension for the x-values and y-values.

What I don't understand and would like to remediate:

  1. Why do I get more y-values when I start from the same dataset?
  2. Can I use different parameters for a function and how? (like a tuple and a single value)
  3. Is my parameter passing for LogL plot that uses functie_f correct?

Here are my attemps without iteration with the same error for the three different codes:

First I tried simply to leave out the iteration for y:


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

Then I tried to iterate x (thinking it would take 1 y-value for every 1 x-value)

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

And I tried to write that under the declaration of y because maybe it also has the dataset x in its function, but that did not change anything (I also tried 'renew kernel to force it to re-run the code)

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

For all three changes here above, I get the (same) following error message:

---------------------------------------------------------------------------
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,)
7
  • You need to change something between function calls. All you're doing is calling the function with the exact same parameters every time. Presumably, your data is constant, so that means something about lamb_da needs to change each call in order to get different results from each call. It's like in math if you have f(x) = x^2, you're asking why f(4) keeps giving you 16. Of course it will, you're evaluating the function at 4 every time. Commented Sep 4, 2024 at 12:06
  • Does the x not come from the dataset then? Is it not f(dataset[0],lambda) then f(dataset[1], lambda) , f(dataset[2], lambda), f(dataset[3], lambda),f(dataset[4], lambda) and done!? Same for y, why does it go over all datasets and then go back to it for 5 times? if I say for i in dataset, is it not first in dataset, second in dataset, third in dataset, fourth in dataset, fifth in dataset , done? Why does it go back? Commented Sep 4, 2024 at 12:25
  • Yes and no. for i in dataset indeed means that i is first the first element of dataset, then the second and so on. BUT you are passing not i to functie_f but the full list dataset, for each value i is assuming. And functie_f is apparently able to handle single values as well as lists of values, indirectly answering your 2nd question. Commented Sep 4, 2024 at 13:32
  • You're passing in the entire dataset, but your last operation is to sum the values, so that will give you a single number. Also, because your dataset is a list and not numpy array, lamb_da*x does not do what you think it does. Commented Sep 4, 2024 at 13:55
  • Conclusion: I abandon the iteration (cause I don't want to pass the whole dataset as a value)? So I'm back to the expression : y=functie_f(dataset,lamb_da) plt.plot(dataset,y) without iteration, but then I have an error message of not having the same dimension for x and y. Why is that? Because I never give a dimension to y other than the one for x, but when it is called in the plot it has twice the dimension of x (see error message in question)? How can I avoid that? Commented Sep 4, 2024 at 15:05

1 Answer 1

0

When dataset is a regular python list, lamb_da*x is a list times an integer, which just duplicates the list x times. For example:

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

You are also doing a list comprehension in this line:

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

There, you are calling the function the exact same way every time, so you are getting len(dataset) identical results.

You can fix this in one of two ways.

  1. You can keep the list comprehension but actually loop over the dataset.
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)

Your mistake in all your loops was you were creating the variable you need (you called it i or x in different cases) but not actually using those values.

  1. You can convert dataset to a numpy array and remove the list comprehension.
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)

Both methods give this result:

Note: the line looks as it does (going back and forth) because your dataset values are not sorted.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.