Here are my notes for how to create data plots using various tools.

  • Some cool people I know use Veusz which seems pretty good. It’s cross platform.

DIY

plotutils

Make sure it’s installed with something like this:

sudo yum install plotutils

From the package description:

The GNU plotutils package contains software for both programmers
and technical users. Its centerpiece is libplot, a powerful C/C++
function library for exporting 2-D vector graphics in many file
formats, both vector and raster. It can also do vector graphics
animations. Besides libplot, the package contains command-line
programs for plotting scientific data. Many of them use libplot to
export graphics.

The documentation is in stupid info page format. Some nice person has webified it here.

The simplest usage is something like this:

ls -l /xed | awk '{print $7,$5}' | sort -n | graph -T png > test.png

This plots the size of files against what day of the month they were touched on. Not useful but it illustrates the kind of data that goes to the graph command and how it is used.

  • --bitmap-size="800x300" = Size of finished bitmap file (if bitmap).

  • -[x|y] <Min> <Max> = Limit of plot.

  • -L <Label> = Top label (or title).

  • -I e = Error bars. Data should be in "x y error" format (triples).

  • -[X|Y] <Label> = Axis labels.

  • -m <N> = Line mode (N can be -1=invisible, 1=solid, 2=dotted, 3=dotdash, 4=shortdash, 5=longdashed)

  • -S <n> <s> = Symbol marker (see below)

  • -a = Abscissa values are auto generated. This allows for plotting a single stream of Y values. The X values will just be 1,2,3,…N.

  • -l <x|y> = Logarithmic axis.

  • -g <n> = Grid style (0= none, 1= pair of axis and ticks and labels, 2= add box, 3=add gridlines).

Symbol Styles
    1. dot, 2. plus, (+) 3. asterisk (*) 4. circle 5. cross 6. square 7.
    triangle 8. diamond 9. star 10. inverted triangle 11. starburst
    12. fancy plus 13. fancy cross 14. fancy square 15. fancy diamond
    16. filled circle 17. filled square 18. filled triangle 19. filled
    diamond 20. filled inverted triangle 21. filled fancy square
    22. filled fancy diamond 23. half filled circle 24. half
    filled square
    25. half filled triangle 26. half filled diamond 27. half filled
    inverted triangle 28. half filled fancy square 29. half filled
    fancy diamond 30. octagon 31. filled octagon
An Example
outputs_2_columns_of_numbers.py  | graph --bitmap-size="2400x1800" \
    -L "Example Title" \
    -X "seconds" \
    -Y "excitement" \
    -l y \
    -x 0 32 8 -y .1 100 \
    -T png \
    > latency-c.png

gnuplot

The problem with gnuplot is that it requires that you prepare data files ahead of time. This precludes it from simple use with pipes (as far as I know).

Hmm. Just discovered a possible way.

Make a gnuplot set up file with all the stuff you need:

plotsetup.gnuplot
    set style data dots
    set yr [-30:300]
    set xr [0:3520]
    plot '-'

And then do something like:

datalogger | cat plotsetup.gnuplot - | gnuplot -persist

The -persist option keeps the plot window open after the main process closes.

Also one can do interesting things like:

plot "< awk '{print $1-2013 $2}' my_data_file.dat"

This will take the raw dumps of data (packets sniffed in this case) and run them through the cleanup program d2cleanS where they will emerge as a lot of columns of clean numbers. Then column 5 is X and column 70 is Y. I’m plotting both the AT and SO runs on the same space.

plot "< ./d2cleanS ./dump.AT.dir2.II" using 5:70, \
     "< ./d2cleanS ./dump.SO.dir2.II" using 5:70

Even more complex. Four plots, 2 properties (speed X and speed Y) from 2 different entities (race cars). The speed Y is a different scale than X and I want magnitudes so negative values of Y are fixed with the abs() function.

set xr [0:300]
set y2r [0:30]
plot "< ./d2cleanS ./dump.AT.Cork.II" using 5:48, \
     "< ./d2cleanS ./dump.SO.Cork.II" using 5:48, \
     "< ./d2cleanS ./dump.AT.Cork.II" using 5:(abs($49)) axes x1y2, \
     "< ./d2cleanS ./dump.SO.Cork.II" using 5:(abs($49)) axes x1y2

Here’s one where I needed to line up two data sets with different timestamp offsets. I also wanted the dots joined with lines since they were too sparse otherwise.

set xr [0:210]
set yr [-1:1]
plot "< ./d2cleanR ./dump.AT.Cork.II" using ($1-1371182873):5 with lines, \
     "< ./d2cleanR ./dump.SO.Cork.II" using ($1-1371183236):8 with lines

And for output:

set out "|lpr -P MyLaserJet"

General

plot "datafile" using 1 2 3
plot "datafile" using 1:2 1:3
plot "datafile" using 1 2 3

You can also have the file read in interesting ways:

plot "datafile" using 2:1 "%f%*f%f"

Where the last column there is the scanf format string.

From multiple files separate with commas:

plot "./clt_dfs_sx_sy.SO.Cork.II" using 1:2, "./clt_dfs_sx_sy.AT.Cork.II"

Output

When you’ve chosen your output device, use the test command to have a look at the capabilities.

aqua aed512 aed767 amiga aifm apollo atari bitgraph cgi gpr iris4d
kc_tek40xx km_tek40xx next pm regis selanar sun tek40D10x tek40xx VMS
vttek unixplot unixpc windows x11 hercules cga mcga ega vga vgamono
svga att
unknown table dumb dxy800a
excl imagen ln03 post corel prescribe kyo qms dxf fig bfig hcgi mif
pbm rgip tgif hp2623A hp2648 hp7580B hpgl hpljii hpdj hppj pcl5 latex
eepic
emtex pstricks tpic mf
pop push

Polar

Works fine. The important bits are:

set angle degrees
set tics scale 0

Here’s an example of some vehicle sensors measuring a track. 0 deg is straight ahead and 90 is directly to the vehicle’s left. The sensor reads the distance to the edge of the road. This should produce a straight edge, but something is not right.

This shows how to have a self contained data + set up file for gnuplot. Just run gnuplot polarexample.gnuplot.

An Example of Polar
set polar
set angles degrees
set term dumb
set tics scale 0
set style line 2 pt 14
plot "-" with linespoints pointtype 15 notitle
 10 76.9156
 20 39.4343
 30 26.6504
 40 20.2422
 50 13.8997
 60 9.85593
 70 8.06027
 80 7.23516
 90 6.99576
e
Resulting Polar Plot
  14 +--------+--------+-------+--------+--------+--------+-------+--------+
     |                    ***********O*****************                    |
  13 +             O*****O                             ****************O   +
     |            *                                                        |
     |           *                                                         |
  12 +          *                                                          +
     |         *                                                           |
  11 +        *                                                            +
     |       O                                                             |
  10 +       *                                                             +
     |      *                                                              |
     |      *                                                              |
   9 +     *                                                               +
     |   O                                                                 |
   8 +  *                                                                  +
     | O                                                                   |
     |O                                                                    |
   7 O                                                                     +
     |                                                                     |
   6 +--------+--------+-------+--------+--------+--------+-------+--------+
     0        10       20      30       40       50       60      70       80

Note that I used pointtype 15 because it gives an "O" which looks better than the default "A". Use the test command to see your options.

PNG

I had trouble making PNGs that weren’t messed up. I needed to have an environment variable set like:

export GNUPLOT_DEFAULT_GDFONT=verdana

After that I just had a setup file like:

set term png small size 1680,504
set yr [-30:30]
set xr [0:200]
plot '-' notitle

Then I used bash to convert my data files:

for X in trackanalysis-????; do echo $X; cat gpsetup $X | \
gnuplot - > $X.png ; done

Useful Settings

# Using what right now?
show terminal

# Make PNGs
set terminal png
size 800,600
[no]transparent

# PostScript
set term post portrait color "Times-Roman" 14

# SVG - warning: produces XML, need to pipe that off somewhere.
set term svg size 600,400

# ASCII Art
set terminal dumb

# Wxt - wxWidget interactive window, works pretty well
# The number (0 here) is plot window number. Juggle multiple windows
# with this.
set term wxt 0

# X11 - old school X
set twerm x11 enhanced font "arial,15"

# Plotting
plot "file1","file2"

# Borders
set border
unset border
show border

# Labels
set label 0 "The Origin" at 0,0 center font "Arial,12"
unset label 0 # Can use any integer or not use them and auto increment.

# Linetype
set linetype 1 lc rgb "dark-red" lw 2 pt 5

# Log - pick axes x, y, xy Also can specify a base (like 2) 10 is default
set logscale xy

# Margin - distance between plot border and edge of canvas
# Units are height and width of characters. Whatever that means.
set bmargin 2

# Multiplot... Many plots on one canvas. Look up:
set multiplot { layout <rows>,<cols> }
# Do some plotting
unset multiplot # This should cause them to be rendered.

# Ticks
set xtics 0,5,10
set ytics add (3.141)
set mytics 10 # minor tics

Tics

They’re there, just not so cluttered.

set tics scale 0

Or gone entirely.

unset xtics
unset ytics

Matplotlib

What if you don’t want an interactive window?!

Use the "Agg" back end.

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig('myfig')

I think "AGG" means "anti-grain graphics". There are other back ends such as "PS", "PDF", "SVG",

Other Possible Ways To Suppress Interactive Enthusiasm
  • matplotlib.interactive() - Sets interactivity state.

  • matplotlib.pyplot.ioff() - Also ion. (Didn’t work for me.)

  • Add interactive : False to $MATPLOTLIBRC/matplotlibrc.

RGB

If you read in an image using matplotlib.image.imread() you will get an RGB image, but if you read it in using OpenCV cv2.imread() this will give you a BGR image.

matplotlib

RGB

OpenCV

BGR

Examples

Example Program
#!/usr/bin/python
import math
import numpy as np
import matplotlib.pyplot as plt

# Define axes' range.
plt.axis([0, 6, -10, 20]) # 0 to 6 on X, 0 to 40 on Y

# Normal arrays work fine.
plt.plot([1,2,3,4], [1,4,9,16], 'ro') # r=Red, o=Ohs(dots)
plt.plot([1,2,3,4], [1,4,9,16]) # Dots and lines. Z painted in order.
plt.plot([1.5,2.5,3.5,4.5], [16,9,4,1], 'b^') # r=Blue, ^=Tris

# Normal math functions work.
X= [x/60.0 for x in range(600)]
plt.plot(X,[8*math.cos(5*x) for x in X])

# Numpy arrays are good.
x= np.arange(0,6,.01)
y= 10 * np.sin(x*10)
plt.plot(x,y,'g--') # g=Green, --=Dashed

# Output.
plt.savefig('plottest.svg',format="svg") # "png" is good too.
plt.show() # Seems to clear the image too, so save it first.

For subplot() and add_subplot(), the arguments work like this.

subplot(nrows,ncols,plot_number)
Multiple Subplots
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(2, 1, 1)
ax.imshow(np.random.random((10,10)))
ax.autoscale(False)
ax2 = fig.add_subplot(2, 1, 2, sharex=ax, sharey=ax)
ax2.imshow(np.random.random((10,10)))
ax2.autoscale(False)
plt.show()

Some Features I’ve Used

  • plt.axes - Useful for setting aspect="equal".

  • plt.axis - Range of axes.

  • plt.axhline - Draws a horizontal line through the plot at the specified position. Good for putting origin lines at 0.

  • plt.axvline - Draws a vertical line through the plot at the specified position. Good for putting origin lines at 0.

  • plt.fill_between - Colors the plot between a specified range, for example, everything below your function.

  • plt.grid - Show grid lines on the plot.

  • plt.xlim - Define the X min and max plotting range.

  • plt.ylim - Define the Y min and max plotting range.

  • plt.xticks - Takes a list that represents where ticks go on X axis.

  • plt.yticks - Takes a list that represents where ticks go on Y axis.

  • plt.polar - Create a circular polar plot.

  • plt.scatter - Create a scatter plot.

  • plt.plot - Create a data line plot.

  • plt.saveconfig(filename.svg,formate="svg") - Also "png".

  • plt.show - Send to interactive window. Erases the plt object, so do this last.

  • matplotlib.image.imsave(FILENAME,image_array) - Save image files.