0

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

The above error is what I got for the below code intended to plot the piecewise function created. Can't figure it out.

import numpy as np
import matplotlib.pyplot as plt
def f(x):
    if x>=0 and x<=1:
        return x
    elif x>1 and x<=2:
        return 2-x
    else:
        return 0

xlist = np.linspace(0,1,num = 1000)
ylist = f(xlist)

plt.plot(ylist,xlist)
plt.show()
1
  • 2
    Your function should handle vectorial input. You need to use vectorial operations ;) Commented Feb 8, 2022 at 17:53

3 Answers 3

2

As per comments, you need to vectorize your method f (and also fix some mistakes):

import numpy as np
import matplotlib.pyplot as plt

def f(x):
    y = np.empty_like(x)
    mask1 = (0 <= x) & (x <= 1)
    mask2 = (1 < x) & (x <= 2)
    mask3 = np.logical_not((0 <= x) & (x <= 2)) #or ~((0 <= x) & (x <= 2))
    y[mask1] = x[mask1]
    y[mask2] = 2 - x[mask2]
    y[mask3] = 0
    return y

xlist = np.linspace(-1, 3, num = 1000)
ylist = f(xlist)

plt.plot(xlist, ylist)
plt.show()

You might also find that mask3 is not necessarry and vectorize a method f like this:

def f(x):
    y = np.full_like(x, fill_value=0) #or np.zeros_like(x)
    mask1 = (0 <= x) & (x <= 1)
    mask2 = (1 < x) & (x <= 2)
    y[mask1] = x[mask1]
    y[mask2] = 2 - x[mask2]
    return y

enter image description here

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

1 Comment

Sometimes you wouldn't need to create a mask number 3 (and use y = np.zeros_like(x) instead). I've implemented it in a way that works in a more general way assuming OP would want to pad remaining values with anything else than zeros.
0

What I understood is , you are basically comparing an array with a number which should not be the case here, the code provided might help you with solution,

import numpy as np
import matplotlib.pyplot as plt
def f(x):
    if x>=0 and x<=1:
        return x
    elif x>1 and x<=2:
        return 2-x
    else:
        return 0

xlist = np.linspace(0,1,num = 1000,endpoint=False)
ylist = np.array([f(num) for num in xlist])

plt.plot(xlist,ylist)
plt.show()

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

You can use the function you have already defined and vectorize is using np.vectorize.

import numpy as np
import matplotlib.pyplot as plt
    def f(x):
    if x>=0 and x<=1:
        return x
    elif x>1 and x<=2:
        return 2-x
    else:
        return 0.    # make this change to ensure float values

xlist = np.linspace(0,1,num = 1000)
ylist = np.vectorize(f)(xlist)

plt.plot(ylist,xlist)
plt.show()

The issue you are running into in your code is that you are passing an array to f rather than applying f element-wise, so any comparison gives an array of True or False values; this is what is ambiguous in the error message. Using np.vectorize will change the function defined to apply to each element of the array and give you the desired output.

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.