-1

I want to plot f(x) = x^(2/3) using python, however, I'm only able to get it to plot for the positive values of x.

Does anyone have any ideas where I'm going wrong?

import numpy as np
import matplotlib.pyplot as plt

# Define the function
def f(x):
    return x ** (2/3)

# Generate x values for both positive and negative x
x_positive = np.linspace(0, 10, 200)
x_negative = np.linspace(-10, 0, 200)

# Calculate corresponding y values for both sets of x values
y_positive = f(x_positive)
y_negative = f(x_negative)

# Plot
plt.figure(figsize=(8, 6))

# Plot for positive x
plt.plot(x_positive, y_positive, label=r'$f(x) = x^{2/3}$', color='blue')

# Plot for negative x
plt.plot(x_negative, y_negative, linestyle='dashed', color='blue')

plt.title('f(x) = x^(2/3)')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.grid(True)
plt.legend()
plt.ylim(-10, 10)  
plt.xlim(-10, 10)  
plt.axhline(y=0, color='black', linewidth=0.8)  # x-axis
plt.axvline(x=0, color='black', linewidth=0.8)  # y-axis
plt.show()  

Which results in a warning, and a plot with half the x range.

C:\Users\...\AppData\Local\Temp\ipykernel_35264\1241025677.py:3: RuntimeWarning: invalid value encountered in power
  return x ** (2/3)

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
smdr
  • 15
  • 3
  • Hi, thanks - it explains why I'm only seeing positive numbers but the solution proposed doesn't seem to solve my problem. I tried: ``` def f(x): return np.sign(x) * (np.abs(x)) ** (2/3) ``` And the graph python produces looks like an s-shape where positive values of x correspond to positive values of y, and negative values of x correspond to negative values of y. However, I think it should produce a v-shaped graph where positive values of x correspond to positive values of y, and negative values of x correspond to positive values of y. – smdr Aug 29 '23 at 15:28
  • 2
    By definition, `x**a` is mathematically defined only if `x > 0` when `a` is not an integer. So it's fair that numpy forces it that way. You could rephrase your function as `(x**2)**1/3`, which is equivalent to `abs(x) ** 2/3`; then it is defined for all non-zero `x`. I don't think `np.sign` make sense; I mean it would be `np.sign(x) ** 2/3` because `(xy)**a == x**a * y**a`, but then we run into the power of negative number dilemma again. – Quang Hoang Aug 29 '23 at 15:51
  • `x_negative = np.linspace(-10, 0, 200, dtype=np.complex128)`, which still produces `ComplexWarning`, but also plots the function. – Trenton McKinney Aug 30 '23 at 18:40

1 Answers1

1

The reason only the plot for positive x values is visible in the graph of the function f(x) = x^(2/3) is because raising a negative number to the power of 2/3 results in a complex number. In a 2d graph, complex numbers cannot be directly plotted. So, the graph only shows the portion corresponding to the real values of x - which are the positive values. But you can plot the absolute values of the negative x values and indicate the negative sign in the plot.

import numpy as np
import matplotlib.pyplot as plt

# Define the function
def f(x):
    return np.power(np.abs(x), 2/3) * np.sign(x) # Here is the change

# Generate x values for both positive and negative x
x_positive = np.linspace(0, 10, 200)
x_negative = np.linspace(-10, 0, 200)

# Calculate corresponding y values for both sets of x values
y_positive = f(x_positive)
y_negative = f(x_negative)

# Plot
plt.figure(figsize=(8, 6))

# Plot for positive x
plt.plot(x_positive, y_positive, label=r'$f(x) = x^{2/3}$', color='blue')

# Plot for negative x
plt.plot(x_negative, y_negative, linestyle='dashed', color='blue')

plt.title('f(x) = x^(2/3)')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.grid(True)
plt.legend()
plt.ylim(-10, 10)  
plt.xlim(-10, 10)  
plt.axhline(y=0, color='black', linewidth=0.8)  # x-axis
plt.axvline(x=0, color='black', linewidth=0.8)  # y-axis
plt.show()
KIDUS Sisay
  • 67
  • 1
  • 3
  • 8
  • `x**(.666)` produces the warning and `np.nan` for the negative elements of `x`. `nan` values are not plotted. If `x` is complex (even with just a `0j` imaginary term), the result will be complex (and no warning). The `np.abs()` will match the `((x**2)**(1/3)` or `np.abs(x)**(2/3)` cases. I'm don't think your `f` should include the `sign` term. – hpaulj Aug 29 '23 at 17:29
  • Your first sentence is not mathematically correct. In math terms, `x^(2/3)` is well-defined and will not produce imaginary results for negative inputs. When x is -8, for example, the result is 4. However, the computer doesn't realize that we asked for 2/3; it only sees 0.6666..., and that IS a problem. – Tim Roberts Aug 30 '23 at 18:44