Search code examples
pythonpython-3.xmatplotlibscipycomplex-numbers

Not able to plot a smooth complex mathematical function with matplotlib, why?


I am trying to plot a complex function with matplotlib. This function plot a normal 1D function if the imaginary part is 0 (and this works) and the whole complex function, as a 2D plot, if the imaginary part is not 0. This is the function:

import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as sci

def plotter_complex( real_part, imaginary_part, a, b, n, coefficient ): 
        x = np.arange( a, b, ( ( b-a ) / 10 ) )

        def func( x ): #This are two functions I defined to plot the function.
            return coefficient * ut.e_parser( real_part, imaginary_part, n, x )
        
        my_label = "Normalized wave-function f(x) for n = " + str( n )
        plt.figure( figsize = ( 8, 6 ), dpi = 80 )
        plt.xlabel( "Re: f(x)" )
        plt.ylabel( "Im: f(x)" )
        plt.title( my_label )

        if imaginary_part == "0":
            X_Y_Spline = sci.make_interp_spline( x, func( x ) )
            X = np.linspace( x.min(), x.max(), 500 )
            Y = X_Y_Spline( X )
        
            plt.xlabel( "x" )
            plt.ylabel( "Re: f(x)" )
            plt.plot( X, Y, color = "green" )
        else:
            X_Y_Spline = sci.make_interp_spline( np.real( func( x ) ), np.imag( func( x ) ) )
            X = np.linspace( x.min(), x.max(), 500 )
            Y = X_Y_Spline( X )
            
            plt.plot( X, Y, color = "green" )

        plt.show()

Obviously if I try:

import numpy as np
plotter_complex( "np.cos(x)", "np.sin(x)", -1, 1, 3, 4 )

It gives me:

Traceback (most recent call last):
  File "src/main.py", line 167, in <module>
    main()
  File "src/main.py", line 20, in main
    ft.plotter_complex( "np.cos(x)", "np.sin(x)", -1, 1, 3, 4 )
  File "/home/gianluca/WaveNCC/src/functions.py", line 231, in plotter_complex
    X_Y_Spline = sci.make_interp_spline( np.real( func( x ) ), np.imag( func( x ) ) )
  File "/home/gianluca/.local/lib/python3.8/site-packages/scipy/interpolate/_bsplines.py", line 786, in make_interp_spline
    raise ValueError("Expect x to be a 1-D sorted array_like.")
ValueError: Expect x to be a 1-D sorted array_like.

And it's right, since I am trying to interpolate two functions. But I don't understand how I could smooth the complex function otherwise. Thanks.

PS: If I try to plot the normal complex function it works. The fact is that I am not able to smooth it.


Solution

  • A circle with 10 points:

    In [131]: x = np.linspace(0,2*np.pi,10)
    In [132]: c = np.cos(x); s = np.sin(x)
    In [133]: plt.plot(c,s)
    Out[133]: [<matplotlib.lines.Line2D at 0x7f2514b98040>]
    

    Interpolate c and s to 100 points:

    In [136]: from scipy.interpolate import make_interp_spline
    In [137]: X = np.linspace(0, 2*np.pi,100)
    In [138]: C = make_interp_spline(x,c)(X)
    In [139]: S = make_interp_spline(x,s)(X)
    In [140]: plt.plot(C,S)
    Out[140]: [<matplotlib.lines.Line2D at 0x7f2508447c70>]
    

    comparison plot with direct calculation of those 100 points:

    In [141]: plt.plot(np.cos(X),np.sin(X))
    Out[141]: [<matplotlib.lines.Line2D at 0x7f2508455190>]
    

    figure 1