If you're new to Python
and VPython: Introduction

A VPython tutorial

Pictures of 3D objects

What's new in VPython 6

VPython web site
VPython license
Python web site
Math module (sqrt etc.)
Numpy module (arrays)


In this section we describe features for plotting graphs with tick marks and labels. In the image above the user is dragging the mouse to see the coordinates at the intersection of the crosshairs. This image comes from the VPython demo program graphtest.py. Graphs can also be log-log or semilog (see below).

Here is a simple example of how to plot a graph (arange creates a numeric array running from 0 to 8, stopping short of 8.1):

from visual import * # must import visual or vis first
from visual.graph import * # import graphing features
f1 = gcurve(color=color.cyan) # a graphics curve
for x in arange(0, 8.05, 0.1): # x goes from 0 to 8
    f1.plot(pos=(x,5*cos(2*x)*exp(-0.2*x))) # plot

Importing from visual.graph makes available all Visual objects plus the graph plotting module. The graph is autoscaled to display all the data in the window.

A connected curve (gcurve) is just one of several kinds of graph plotting objects. Other options are disconnected dots (gdots), vertical bars (gvbars), horizontal bars (ghbars), and binned data displayed as vertical bars (ghistogram; see later discussion).

When creating gcurve, gdots, gvbars, or ghbars, you can optionally give a list of data points, such as pos=[(10,20), (50,30), (-5,-3)], or specify a color, such as color=color.cyan. After creating one of these graphing objects, you can add a single point or a list of additional points:

f1.plot(pos=(100,-30)) # add a single point
f1.plot(pos=[(100,-30),(20,50),(0,-10)]) # add a list

When you add points, you can optionally specify a color for these points that is different from the default color of the object:

f1.plot(pos=(100,-30), color=color.red)

You can plot more than one thing on the same graph:

f1 = gcurve(color=color.cyan)
f2 = gvbars(delta=0.05, color=color.blue)
for x in arange(0., 8.05, 0.1):
    f2.plot(pos=(x,4*cos(0.5*x)*exp(-0.1*x)))# vbars

Special options for gcurve, gdots, gvbars, and ghbars

For gcurve if you specify dot=True the current plotting point is highlighted with a dot, which is particularly useful if a graph retraces its path. You can specify a shape attribute "round" or "square" (default is shape="round") and a size attribute, which specifies the width of the dot in pixels (default is size=8). By default the dot has the same color as the gcurve, but you can specify a different color, as in dot_color=color.green.


For gvbars and ghbars you can specify a delta attribute, which specifies the width of the bar (the default is delta=1).

If you say g = gcurve(), g.gcurve is a curve object used to represent the gcurve.

If you say g = gdots(), g.dots is a points object used to represent the gdots.

If you say g = gvbars(), g.vbars is a faces object used to represent the vbars.

If you say g = ghbars(), g.hbars is a faces object used to represent the hbars.

Overall gdisplay options

You can establish a gdisplay to set the size, position, and title for the title bar of the graph window, specify titles for the x and y axes, and specify maximum values for each axis, before creating gcurve or other kind of graph plotting object:

gd = gdisplay(x=0, y=0, width=600, height=150,
      title='N vs. t', xtitle='t', ytitle='N',
      foreground=color.black, background=color.white,
      xmax=50, xmin=-20, ymax=5E3, ymin=-2E3)

In this example, the graph window will be located at (0,0), with a size of 600 by 150 pixels, and the title bar will say 'N vs. t'. The graph will have a title 't' on the horizontal axis and 'N' on the vertical axis. The foreground color (white by default) is black, and the background color (black by default) is white.

Instead of autoscaling the graph to display all the data, the graph in this example will have fixed limits. The horizontal axis will extend from -20 to +50, and the vertical axis will extend from -200 to +5000. If you specify xmax but not xmin, it is as though you had also specified xmin to be 0; similarly, if you specify xmin but not xmax, xmax will be 0. The same rule holds for ymax and ymin.

Offsets: If you specify xmin or ymin to be greater than zero, or xmax or ymax to be less than zero, the crossing point (origin) of the x and y axes will no longer be at (0,0), and the graphing will be offset. If you offset the origin of the graph, you must specify xmax to be greater than xmin, and/or ymax to be greater than ymin.

If you simply say gdisplay(), the defaults are x=0, y=0, width=800, height=400, no titles, fully autoscaled.

Every gdisplay has the attribute display, so you can place additional labels or manipulate the graphing window. The only objects that you can place in the graphing window are labels, curves, faces, and points.

graph1 = gdisplay()
label(display=graph1.display, pos=(3,2), text="P")
graph1.display.visible = False # make the display invisible

You can have more than one graph window: just create another gdisplay. By default, any graphing objects created following a gdisplay belong to that window, or you can specify which window a new object belongs to:

energy = gdots(gdisplay=graph2, color=color.blue)

Log-log and semilog plots

When creating a gdisplay, you can specify logarithmic plots by specifying logx=True and/or logy=True. All values must be positive, representing logarithms of numbers between infinitely small (logarithm approaches 0) and infinitely large; that is, numbers such as 0.01, 0.1, 1, 10, 100, etc.

Histograms (sorted, binned data)

The purpose of ghistogram is to sort data into bins and display the distribution. Suppose you have a list of the ages of a group of people, such as [5, 37, 12, 21, 8, 63, 52, 75, 7]. You want to sort these data into bins 20 years wide and display the numbers in each bin in the form of vertical bars. The first bin (0 to 20) contains 4 people [5, 12, 8, 7], the second bin (20 to 40) contains 2 people [21, 37], the third bin (40 to 60) contains 1 person [52], and the fourth bin (60-80) contains 2 people [63, 75]. Here is how you could make this display:

from visual import * # must import visual or vis first
from visual.graph import *
agelist1 = [5, 37, 12, 21, 8, 63, 52, 75, 7]
ages = ghistogram(bins=arange(0,80,20), color=color.red)
ages.plot(data=agelist1) # plot the age distribution
ages.plot(data=agelist2) # plot a different distribution

You specify a list (bins) into which data will be sorted. In the example given here, bins goes from 0 to 80 by 20's. By default, if you later say


the new distribution replaces the old one. If on the other hand you say

ages.plot(data=agelist2, accumulate=True)

the new data are added to the old data.

If you say the following,

ghistogram(bins=arange(0,50,0.1), accumulate=True,

each plot operation will accumulate the data and average the accumulated data. The default is no accumulation and no averaging.

gdisplay vs. display

A gdisplay window is closely related to a display window. The main difference is that a gdisplay is essentially two-dimensional and has nonuniform x and y scale factors. When you create a gdisplay (either explicitly, or implicitly with the first gcurve or other graphing object), the current display is saved and restored, so that later creation of ordinary VPython objects such as sphere or box will correctly be associated with a previous display, not the more recent gdisplay.