Today I used to be pouring through Complex Variables and Analytic Functions by the esteemed Fornberg and Piret, trying my best to wrap my mind around how complex-valued functions behave. Mentally vizualization such functions is extra difficult since they take an actual and an imaginary input, and outputs two components as well. Due to this fact, a single 3-D plot shouldn’t be sufficient to see how the function behaves. Slightly, we’ve got to separate such a visualization into separate plots of the imaginary and real parts, or alternatively by magnitude and argument, or angle.
I desired to have the ability to mess around with any function I could consider, drag and zoom around its plots, and explore it in visual detail to grasp the way it resulted from the equation. For such a task, Wolfram Mathematica is a wonderful starting tool.
plotComplexFunction[f_]:=Module[{z,rePlot,imPlot,magPlot,phasePlot},z=x+I y;rePlot = Plot3D[Re[f[z]],{x,-2,2},{y,-2,2},AxesLabel->{"Re(z)","Im(z)","Re(f(z))"},Mesh->None];
imPlot = Plot3D[Im[f[z]],{x,-2,2},{y,-2,2},
AxesLabel->{"Re(z)","Im(z)","Im(f(z))"},
Mesh->None];
magPlot = Plot3D[Abs[f[z]], {x, -2, 2}, {y, -2, 2},
AxesLabel -> {"Re(z)", "Im(z)", "Abs(f(z))"},
Mesh -> None,
ColorFunction -> Function[{x, y, z}, ColorData["Rainbow"][Rescale[Arg[x + I y], {-Pi, Pi}]]],
ColorFunctionScaling -> False];
phasePlot=DensityPlot[Arg[f[z]],{x,-2,2},{y,-2,2},
ColorFunction->"Rainbow",
PlotLegends->Automatic,
AxesLabel->{"Re(z)","Im(z)"},
PlotLabel->"Phase"];
GraphicsGrid[{{rePlot,imPlot},{magPlot,phasePlot}},ImageSize->800]];
f[z_]:=(1/2)*(z+1/z);
plotComplexFunction[f]
https://github.com/dreamchef/complex-functions-visualization
https://github.com/dreamchef/complex-functions-visualization
I wrote the above Mathematica code to supply a grid of plots showing the function in each ways just described. On the highest, the imaginary and real parts of the function
are shown, and on the underside, and the magnitude, and the phase shown in color:
After fooling around with a couple of functions using this code and convincing myself they made sense, I used to be fascinated with getting the identical functionality in Python, to attach it to my other mathematical programming projects.
I discovered a wonderful project on GitHub (https://github.com/artmenlope/complex-plotting-tools) which I made a decision to make use of as a place to begin, and potentially contribute to in the long run. The repo provided a very simple interface for plotting complex-valued functions in a wide range of ways. Thanks https://github.com/artmenlope! For instance, after importing numpy
, matplotlib
, and the repo’s cplotting_tools
module defining the function and calling cplt.complex_plot3D(x,y,f,log_mode=False)
produces the next:
These are all for a similar f(z) as above. To view the side-by-side imaginary and real parts of the function, use cplot.plot_re_im(x,y,f,camp="twilight",contour=False,alpha=0.9
:
Moreover, the library provides other cool ways to check functions, including a stream plot:
The library shows a variety of promise and is comparatively easy to make use of! It does require a pts
variable to be defined that encodes the poles and zeros of the given function. Wolfram doesn’t require this since it computes the locations of those points under the hood. It will save a variety of effort for the user if complex-plotting-tools had this functionality as well. I plan to implement that is into the module within the near future.
Within the meantime, rejoice plotting with Wolfram and Python, and share your thoughts and questions in comments below, connect with me on LinkedIn or collaborate with me on GitHub!
Unless otherwise noted, all images were created by the creator.