Plotting Antenna Pattern

For my pymininec project (a re-implementation of the original Mininec [1] in Python, see the pymininec README for a description on how I was able to reverse-engineer 40 year old Basic code), I had needed a method to graphically display the results. So at first I had included a visualization tool for antenna pattern in pymininec.

But after I had added a quick & dirty parser for the output of nec2c, it turned out, the program is useful on its own. So I made it a standalone program and named it plot-antenna.

NEC (numerical electromagnetics code) was originally developed at the Lawrence Livermore National Laboratory in Fortran. Up to version 2 this is free software, later versions (they're at version 5 of NEC now) are non-free. Neoklis Kyriazis translated the Fortran version of NEC-2 to C and called it nec2c. He did some optimizations, e.g. include the separate program SOMNEC (for computing a Sommerfeld/Norton ground model) directly into nec2c and got rid of many compile-time limits of the original Fortran code. The C version nec2c is one of a small number of open source antenna modelling programs. It is a command-line utility that compiles an antenna description into an output text file with a lot of tables. There are other programs like xnecview that can display antenna pattern from this output.

Note that I didn't find an official web-page for nec2c – it is included in Debian and Ubuntu (Ubuntu also is searching for the official upstream version) and it seems it was originally hosted on Google Code. There is a version on github with a link to another version on github. The software seems to be unmaintained these days – not much of a problem since NEC version 2 doesn't get any updates for some decades now.

Now back to plot-antenna: Originally the program only had a parser for output of pymininec (and of the original Mininec [1] program in Basic). I later added a parser for NEC. The current parsers are quick & dirty implementations and may not be very robust – but they do work for me.

The first version used Matplotlib for the graphic display and this is still supported. Originally I had implemented azimuth and elevation pattern and a 3d display.

Recently, after having come across plotly I added html/javascript output using the plotly library. The 3d capabilities of plotly are much better than those of Matplotlib – even with 1 degree resolution of the antenna angles (i.e. 180 * 360 3D points) the display still runs smoothly in the browser (Firefox). With the Matplotlib 3D plot, we need to use 5 degree resolution (36 * 72 3D points) otherwise rotating the display is very sluggish. You can try the plotly version yourself below (or you might want the full window antenna plot):

Not to mention zooming: This works fine in plotly (using the scroll wheel of the mouse in the graphics above) and doesn't seem to be implemented at all in Matplotlib.

In the plotly version we display the plots for all frequencies in a single plot. For the 3D view all except the currently-selected frequency are hidden. You can select the frequency for which the plot should be displayed in the legend on the right side.

The best feature in plotly is the live-display of the 3D-coordinates of the surface on mouse-over. In the current implementation this displays azimuth and elevation angles as well as the absolute and relative gains at the selected point on the antenna pattern.

On the other hand I needed several workarounds in plotly:

  • There is a bug in hover when displaying coordinates

  • plotly does not support menus for 3D surfaces, I had to put an additional (empty, with one white dot) graphics into the same display for showing the menu. The menu is used when an antenna pattern is computed for a set of frequencies. In that case the frequencies can be selected in the menu on the right side.

  • In plotly there is no way to only show a single menu item at a time. I wanted the menu buttons to behave like radio buttons in web interfaces: Clicking on a new frequency should show only the plot for the clicked-on frequency. For 3D plots it does not make much sense to show several 3D plots in a single display. This is achieved with some custom Javascript.

The antenna pattern in the example above is taken from an article by L.B. Cebik [2]. When you compare the pattern in that article to the 3D pattern above (or you look at the azimuth/elevation diagrams in the description of plot-antenna), you'll notice that the plotly 3D view is slighty distorted (the lobe is too long). I've not yet found out if this is a problem of plotly or my use of it. I do try to get an equal aspect ratio in all dimensions by setting xaxis, yaxis, and zaxis range to the same value but as you can see the aspect ratio does not look right.

When we compare this to an azimuth diagram created with plotly:

the dimensions look ok. Notice that also in the 2D diagram you can display the angle (azimuth in this case) on mouse-over. When using Matplotlib, this is also available but the cursor does not snap to the drawn pattern. So with Matplotlib you always have to guess if the cursor is now exactly at the correct position. Also note that, again, you can select the frequency to display in the frequency legend on the right side. But this time you can display the plots for several frequencies at the same time (which does not make much sense in an opaque 3D plot).