Home > Back-end >  Not able to plot a smooth complex mathematical function with matplotlib, why?
Not able to plot a smooth complex mathematical function with matplotlib, why?

Time:02-04

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.

CodePudding user response:

I'm not sure is this correct from the point of view of theory, but if you add sorting of the result along the X axis, then the graph is plotted:

abs, ord = np.real( func( x ) ), np.imag( func( x ) )
abs, ord = zip(*sorted(zip(abs, ord)))
X_Y_Spline = sci.make_interp_spline( abs, ord )

enter image description here

CodePudding user response:

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

  •  Tags:  
  • Related