Introduction

Supermongo (SM) is a domain-specific programming language for creating plots. It was first written in 1987. Astronomers adopted this language as a primary plotting package for data analysis. Many groundbreaking discoveries have been seen using supermongo plots. However, new tools exist for plotting which have evolved from first plotting languages like Supermongo. These new tools provide methods for creating plots with fewer lines of code. They provide better integration into other programming languages and code.

Matplotlib is a domain-specific plotting library for the general-purpose programming language Python. This library provides all the plotting capabilities of Supermongo and more. This post is to provide a 1-to-1 guide for Supermongo experts to apply their knowledge in Python with Matplotlib.

Other Python plotting packages include : bokeh, plotly, vispy


General Comparison

Variables: In Supermongo all variables are global so wherever you change them, within any macro, they change everywhere else. In Python variables have scope. You can use the same variable name in mulitple functions and be sure that they will act independantly.

Plot States: In Supermongo you have a single plot state which you update with the interactive commands. Matplotlib also uses a plot state which you edit with commands.

Object Oriented: Supermongo is a procedural programming language. You write out all the steps and they execute in that order. Python is object oriented meaning you can create data objects and write them into procedures. This method is how your operating system is built and is extremely useful.

Community Support: If you've ever searched the internet for help with Supermongo (chances are you have if you're reading this) you've come across a handful of useful sites: The SM manual, Annika Peter's Guide, Craig Rudick's Tutorial and Rebecca Stanek's Guide. These resources and only a few others are the mainstay of the Supermongo online support.

By contrast the community supporting Matplotlib is immense. Not only is it developed by many people to have lots of functionality, it also has a large user base. If you are unsure how to make some plot thing, a quick internet search often pulls up many solutions.

Python requirements

Because general purpose language you'll need specific subpackages. For this tutorial:

  • maplotlib
  • numpy

Hopefully, these packages came with your installation of Python. You can also install them using the command line utility pip (e.g. pip install numpy) This tutorial will work with both Python 2 and 3.





Getting Started

Working interactively

In Supermongo all your plotting is done either interactively (you type and the plot is modified) or using a script. In Python you do the same.

To use the interactive mode, on the command line type python (better yet try out ipython for more interactive fun). Now you should have a new prompt, probably with '>>>' which you type your python code. (Check out TODO for a python tutorial)

import numpy as np  
x = np.array(10)  
# comment
for i in range(len(x)):
    """ String doc """
    print(" value {} = {}".format(i,x[i]))

Here's some comparisons of interactive mode.

Supermongo

div X11            
set x = {2,3}      
set y = {5,10}     
con x y            
xlabel time        
ylabel temperature 

Python

from matplotlib.pylab import *    
x = [2,3]                         
y = [5,10]                        
plot(x,y)                         
xlabel("time")                    
ylabel("temperature")             
show()

NOTE: The remainder of the tutorial I don't use from matplotlib.pylab import * and instead use import matplotlib.pylab as plt then commands like plt.plot. The reason has to do with how many named things there are and to allow me to make my own plot function different from the default plt.plot function. Basically, it's good coding practice.

Writing Scripts

Both languages allow you to write a script to execute commands. If you're not doing this you really should. In a nut shell, you just write the lines you would type into the interactive mode into a text file and then execute that file. You will want to use Emacs, Sublime Text, TextWrangler or some equivalent text editor.

With Supermongo you write a script with at least one macro, for example:

"script.sm"

main_macro 
    dev x11
    ctype white
    set x=0.0,10.0,1.0
    set y=x**2
    lim x y 
    box
    con x y

Then startup Supermongo using sm enter macro read script.sm and then main_macro to execute.

For Python you write a script similarly

"script.py"

import matplotlib.pylab as plt
import numpy as np

x = np.arange(0.0,10.0,1.0)
y = x**2
plt.plot(x,y)
plt.show()

Then you can run it with python script.py.



Comparisons of Supermongo and Python Plotting

Plotting libraries implement functions to display views of data. One of the basic views is comparing one data parameter (say X) against another (say Y) and just plotting the intersecting points (a.k.a. a scatter plot). In this section, I make direct comparisons of Supermongo to Python plotting methods.

Adding items to plots

Both plotting packages create some plot axes which you can then add views of your data to.

Both plotting packages have methods for adding XY data as lines, points, and with errorbars. Below is the side by side comparison.

Plot Lines

Supermongo

connect x y  

Python

plt.plot(x, y)

Plot Line

Supermongo

line x1 y1 x2 y2

Python

plt.plot([x1, x2],[y1, y2])

Plot Points

Supermongo

points x y

Python

plt.scatter(x, y)              
# or use                      
plt.plot(x, y, linestyle="none")

Plot Errorbars

Supermongo

errory x y yerr
errorx x y xerr

Python

plt.errorbar(x,y,yerr=yerr)         
plt.errorbar(x,y,xerr=xerr)         
plt.errobar(x,y,xerr=xerr,yerr=yerr)

Plot Horizontal Line

Supermongo

hzline y

Python

plt.axhline(y)

Plot Vertical Line

Supermongo

vtline x

Python

plt.axvline(x)

Plot Rectangle

Supermongo

relocate x1 y1 
draw x1 y2     
draw x2 y2     
draw x2 y1     
draw x1 y1     

Python

rec = plt.Rectangle(x1,y1,(x2-x1),(y2-y1))
plt.gca().add_patch(rec)                  

Layout Axis Labels

Supermongo

toplabel title_of_plot
xlabel label_name
ylabel label_name

Python

plt.title("title_of_plot")
plt.xlabel("label_name")
plt.ylabel("label_name")                  

Layout Add Text

Supermongo

relocate x y    
label label_text

Python

plt.text(x, y, "label_text")

Layout Legends

Supermongo

# Draw Rectangle box
relocate xpt= ypt   
# Set ptype,ctype   
dot                 
relocate xpt+dx ypt 
label Item Label    

Python

# just add label keyword        
# to your plot call             
plt.plot(x,y,label="Item Label")
plt.legend()                    
# use help(plt.legend) to find  
# out about keywords            

Plot legends are a pain in Supermongo. If you want a bounding box you need to draw the rectangle yourself specifying every corner. Then you have to specify the exact positions of each label, draw a point with the correct styles at the correct location, then add the text slightly offset. If you want to add/remove labels or if points styles change then you're often thrown into chaos. (Of course you can write macros, but why? when Python makes it so easy!)

The python plt.legend function looks for any plot item you added a lable=? keyword argument to. This includes all lines and points as well as patches like plt.Rectangle and plt.Circle. It's also easy to manipulate the position using the loc=? keyword of plt.legend.

Controlling Plot Styles

In Supermongo you must set the styles globally before adding them to the plot. This can lead to frustrating bugs if their out of order

This one may or may not be red points:

points x y 
ctype red

This causes the points to be red:

ctype red
points x y

In Python you set the plot parameters at the same time you add the item. You do this using keywords in the function call.

plt.scatter(x,y,c='red')

You can find out about all the keywords by typing help(plt.scatter) in the Python terminal or by using an internet search (the internet is your friend). Caveat: Matplotlib has an rc file that sets some global variables. You can learn more about it here.

Alright, here comes the one to one of common styles you'll want to manipulate. The Python answers I'm going to use the most common function; Note though, Matplotlib has some inconsistencies with names and so you should refer to the internet or help if you run into problems in your own implementation.

Point Color

Supermongo

ctype red 
ctype red 
points x y

Python

plt.scatter(x,y,c='r')      
plt.scatter(x,y,c='r')      
# hex colors work           
plt.scatter(x,y,c='#DC322F')

Point Style

Supermongo

ptype 10 3    
ptype 10 3    

Python

plt.scatter(x,y,marker='o')
plt.scatter(x,y,marker='o')

Point Size

Supermongo

expand 1.5
expand 1.5

Python

plt.scatter(x,y,s=100)
plt.scatter(x,y,s=100)

Line Color

Supermongo

ctype red   
ctype red   
connect x y 

Python

plt.plot(x,y,color='r')      
plt.plot(x,y,color='r')      
# hex colors work            
plt.plot(x,y,color='#DC322F')

Line Style

Supermongo

ltype 2    
ltype 2    
connect x y

Python

 plt.plot(x,y,linestyle='--')
 plt.plot(x,y,linestyle='--')
 # or the shortcut           
 plt.plot(x,y,ls='--')       

Line Width

Supermongo

lw 7
lw 7

Python

 plt.plot(x,y,lw=7)
 plt.plot(x,y,lw=7)

More with Matplotlib

In addition to the side by side comparison matplotlib provides you additional ways to plot your data and manipulate your figures.

Modifying Plot Properties

In addition to add items to a plot you want to manipulate properties of the plot itself. For example, you often want to re-size the bounds of the plot.

It's important to talk about the figure. In Supermongo you only ever have one figure which you can add multiple sub-plots to but usually only one. In Matplotlib you have the option to create multiple figures if you store

Figure and Plot

Supermongo

page
box

Python

fig = plt.figure()
ax = fig.add_subplot(1,1,1) # ax = plt.gca() for shortcut

Multipanel Plot

Supermongo

page
window 2 2 1 2

Python

fig = plt.figure()
ax = fig.add_subplot(2,2,4)

Note: For Python, storing the plot in ax is not necessary but it's a best practice to use matplotlib objects.


For multipanel plots Supermongo uses the window command with arguments [number of columns] [number of rows] [x-index] [y-index]. window 2 2 1 2 indicates 2 rows 2 columns and the current plot is the bottom-right.


In Matplotlib there are several ways to accomplish this (add_subplot,plt.subplots,gridspec). I commonly create a figure fig = plt.figure() and add a subplot ax = fig.add_subplot(1,1,1). The arguments are [number of rows] [number of columns] [current plot]. The current plot number starts counting at 1 from the top-left then continues as though you were reading English from left to right, top to bottom. To get the bottom right plot from the Supermongo example I would use ax = fig.add_subplot(2,2,4).

Saving plots to file

Saving in Supermongo requires setting up a state to put the plot into. The following example from Annika Peter shows how to set up the device then save to file (the last hardcopy is critical, you can also use dev x11 to close).

dev postencap my_first_plot.eps
ctype black
set x=0.0,10.0,1.0
set y=x**2
lim x y
box
con x y
ptype 10 3
points x y
xlabel x
ylabel y
hardcopy

Matplotlib does not require you to set anything up prior to building the items. Instead, you can just save out the state or figure with a command. The following example mimics the Supermongo example.

import matplotlib.pylab as plt
import numpy as np
x = np.arange(0.0,10.0,1.0)
y = x**2
fig,ax = plt.subplots()
ax.plot(x,y,marker='o')
ax.set_xlabel("x")
ax.set_ylabel("y")
fig.savefig("my_first_plot.ps")

Note: Matplotlib is smart about it's saving methods. If you want to create a pdf not ps you just use the ".pdf" extension and it will save to that format. Many other formats are supported (e.g. png, pdf, jpg, gif, etc)




Could publish the programming section later


Programming

Supermongo was developed to be plotting language. However, within it's syntax you can specify any programming task which makes it more or less a complete language. However, you should avoid using SuperMongo for more than plots as much as possible. Other programming languages have much better implementations allowing you to write your code faster, debug easier, and for it to run more efficiently.

For example, Python is a complete language which has good implementations of many programming concepts. It's a language not just for plotting but

Syntax Differences

Supermongo

if(a == b) {
   echo True condition for ${a}
} else { 
    if(a == c) {
        echo else if condition
    } else {
        echo else condition
    }
}

Python

if a == b:
    print(f"True condition for {a}")
elif a == c:
    print("else if condition")
else:
    print("else condition")
Supermongo Python
Variables define x 1 x = 1
Arrays set x = {1,2,3} x = [1,2,3]
Array Range set x = 0,10,1 x = list(range(0,10,1))
Conditionals == != > < >= <= # same
And a && b a and b
Or a b a or b
Not !a !a

Shout Outs

Acknowledgments go to Robert Lupton and Patricia Monger for creating SM which really was revolutionary for it's time. Special thanks to Annika Peter, Craig Rudick and Rebecca Stanek for their Supermongo guides. They helped me immensely when I learned Supermongo and in writing this guide.