Search code examples
pythonnumpymatplotlibcomplex-numbers

How to cplot() a conditional function


I want to plot this function defined on complex numbers: if floor(Re(z))%2==0, f(z)=z else f(z)=sin(z)

I tried to code this:

import cplot
import math
import numpy as np

def f(z):
    if math.floor(np.real(z)[0])%2==0:
        res =z
    else:
        res=np.sin(z)  
    return res

plt = cplot.plot(f, (-10, +10, 3000), (-10, 10, 3000),5)
plt.show()

But it didn't work, the program completely ignores the existence of the sin function and I don't know why.


I thought this was because of my usage of math. and np. so I tested a simpler function:

if Re(z)>=0, f(z) =z, else f(z)= sin(z)

import cplot
import numpy as np

def f(z):
    if np.real(z)[0]>=0:
        res =z
    else:
        res=np.sin(z)  
    return res

plt = cplot.plot(f, (-10, +10, 3000), (-10, 10, 3000),5)
plt.show()

This time the existence of z was completely ignored.


I thought maybe the problem came from the [0] in np.real(z)[0] but removing it would yield an error

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

I used them and the result is still the same, it completely ignores z in my second code, also the problem seems to be in the > sign; if I change it to < it completely ignores the sin.


Solution

  • The function you plot should return an array of results, not just the static result for the first item in the input array.

    I'm not a Numpy person, but based on Applying a function along a numpy array I would try something like

    def f(x):
        if np.real(x) >= 0:
            res = x
        else:
            res = np.sin(x)  
        return res
    
    f_v = np.vectorize(f)
    plt = cplot.plot(f_v, (-10, +10, 3000), (-10, 10, 3000),5)
    plt.show()
    

    I'm sure this could be rewritten more elegantly but at least this should show the direction.