Charting

LINGO has a number of features to generate charts of your data.  Chart types currently included are Bar, Bubble, Contour, Curve, Histogram, Line, Network (node based and arc based), Pie, Radar, Scatter, Surface and Tornado.  A description of the functions for each of the various chart types follows.

@CHARTBAR( 'TITLE', 'X-AXIS LABEL', 'Y-AXIS LABEL', 'LEGEND1', ATTRIBUTE1[, ..., 'LEGENDN', ATTRIBUTEN]);

@CHARTBAR will generate a bar chart of one or more attributes.  The bar chart will be displayed in a new window.   @CHARTBAR argument descriptions follow:

TITLE - This is the title to display at the top of the chart.  The title must be in quotes.
X-AXIS LABEL - The x-axis label in quotes.
Y-AXIS LABEL - The y-axis label in quotes.
LEGENDi - The legend to be used to label attribute i in quotes.
ATTRIBUTEi - This is the attribute to chart.  At least one attribute argument must appear.   If multiple attributes appear, the bars will be grouped together.

As an example, consider the following model, CHARTSTAFF, which is a modified version of the staff scheduling example presented in section Primitive Set Example in Chapter 2, Using Sets:

MODEL:

 

SETS:

  DAYS: REQUIRED, START, ONDUTY;

ENDSETS

 

DATA:

  DAYS =     MON TUE WED THU FRI SAT SUN;

  REQUIRED =  23  16  13  16  19  14  12;

ENDDATA

 

SUBMODEL MODSTAFF:

  MIN = @SUM( DAYS( I): START( I));

 

  @FOR( DAYS( J):

   ONDUTY( J) =

    @SUM( DAYS( I) | I #LE# 5:

     START( @WRAP( J - I + 1, 7)));

 

   ONDUTY( J) >= REQUIRED( J)

 

  );

ENDSUBMODEL

 

CALC:

  ! Solve the staffing model;

  @SOLVE( MODSTAFF);

 

  ! Bar chart of required vs. actual staffing;

  @CHARTBAR(

   'Staffing Example',   !Chart title;

   'Day',                !X-Axis label;

   'Employees',          !Y-Axis label;

   'Employees Required', !Legend 1;

   REQUIRED,             !Attribute 1;

   'Employees On Duty',  !Legend 2;

   ONDUTY                !Attribute 2;

  );

ENDCALC

 

END

Model: CHARTSTAFF

Here, we've added a reference to @CHARTBAR to generate a bar chart of staffing requirements vs. staff on duty for each day of the week.  Here's is the bar chart that is generated:

chartstaff

Note that since we specified more than one attribute, the bars for the two attributes for each day of the week are grouped together.  LINGO also automatically labeled each bar using the attributes' parent set DAYS. From the chart it's easy to see that staffing requirements are just met on days Monday through Saturday, while on Sunday we have slightly more staffing than is actually required.

All arguments to charting function are optional, with the exception of the attribute values.  In many cases, if an argument is omitted, LINGO will provide a reasonable default.  For example, if the title is omitted as we have done here:

  ! Bar chart of required vs. actual staffing;

  @CHARTBAR(

   ,                     !Chart title will default to file name;

   'Day',                !X-Axis label;

   'Employees',          !Y-Axis label;

   'Employees Required', !Legend 1;

   REQUIRED,             !Attribute 1;

   'Employees On Duty',  !Legend 2;

   ONDUTY                !Attribute 2;

  );

then LINGO will use the model's file name instead.   Note that you must still include the comma separator when omitting an argument.

The complete list of charting functions supported is given in the table below.  You may also be interested in running the CHARTS.LG4 sample model, which generates examples of all the chart types.

Chart Type

Syntax

Notes

Bar

@CHARTBAR( 'Title', 'X-Axis Label', 'Y-Axis Label', 'Legend1', Attribute1[, ..., 'Legendn', Attributen]);

Multiple attributes will result in bars being grouped.

Bubble

@CHARTBUBBLE( 'Title', 'X-Axis Label', 'Y-Axis Label', 'Legend1', X1, Y1, Size1,[, ..., 'Legendn', Xn, Yn, Sizen]);

Each series of bubbles is represented as a triplet of (x-location, y-location, bubble size).

Contour

@CHARTCONTOUR( 'Title', 'X-Axis Label', 'Y-Axis Label', 'Legend', X, Y, Z);

You can thinks of a contour chart as a 3-dimensional surface chart compressed into two dimensions.  Only one series is allowed and it is represented by a grid (x,y,z) coordinates.

Curve

@CHARTCURVE( 'Title', 'X-Axis Label', 'Y-Axis Label', 'Legend1', X1, Y1[, ..., 'Legendn, Xn, Yn]);

Curves are good for representing two-dimensional (x,y) plots, e.g., y=sin(x) . Multiples curves may be drawn in a single chart, with each curve represented as a series of (x,y) coordinates.  See the sample model CHARTDISTRO for an example of a curve chart.

Histogram

@CHARTHISTO( 'Title', 'X-Axis Label', 'Y-Axis', 'Legend', Bins, X);

If the bin count, Bins, is omitted, LINGO will automatically compute a number of bins that results in a resonably distributed histogram.  Only one histogram may be displayed per chart.

Line

@CHARTLINE( 'Title', 'X-Axis Label', 'Y-Axis Label', 'Legend1', X1[, ..., 'Legendn', Xn]);

Multiple lines can be displayed on a single chart, with each being drawn in a different color.

Netarc

@CHARTNETARC( 'Title', 'X-Axis', 'Y-Axis', 'Legend1', X1, Y1, X2, Y2[, ..., 'Legendn', X1n, Y1n, X2n, Y2n]);

Netarc charts are network charts, where the network is represented by a list of 4-tuples, (x1,y1,x2,y2), where (x1,y1)-i is one end point of arc i and (x2,y2)-i is the other end point of arc i.  Multiple networks may be displayed on a single chart.

An optional fifth argument may be added to a data series to specify whether an arc should display an arrowhead, or not.  For example, our first data series on the left is: X1, Y1, X2, Y2.  We could have added a fifth argument, say A1: X1, Y1, X2, Y2, A1, where A1 is a vector of length equal to the number of arcs.  Each member of A1 should then be set to one of the following values:

0: Undirected arc with no arrow,

1: Arc points from first to second node,

2: Arc points from second to first node, or

3: Bidirectional arc with arrow at both ends.

Netnode

@CHARTNETNODE( 'Title', 'X-Axis Label', 'Y-Axis' Label, 'Legend1', X1, Y1, I1, J1[, ..., 'Legendn', Xn, Yn, In, Jn]);

Netnode charts are network charts, where the network is represented by a  two lists of 2-tuples, (x,y) and (i,j), where the (x,y) are the coordinates of each node in the network and the (i,j) give the indices of two nodes from the (x,y) list   that exist as an arc in the network.  Multiple networks may be displayed on a single chart.

An optional fifth argument may be added to a data series to specify whether an arc should display an arrowhead, or not.  For example, our first data series on the left is: X1, Y1, I1, J1.  We could have added a fifth argument, say A1: X1, Y1, I1, J1, A1, where A1 is a vector of length equal to the number of arcs.  Each member of A1 should then be set to one of the following values:

0: Undirected arc with no arrow,

1: Arc points from first to second node,

2: Arc points from second to first node, or

3: Bidirectional arc with arrow at both ends.

Pie

@CHARTPIE( 'Title', 'Legend', X);

Only one attribute may be displayed in a pie chart.

Radar

@CHARTRADAR( 'Title', 'Legend1', X1[, ..., 'Legendn', Xn]);

Multiple attributes can be displayed, with each being in a different color.

Scatter

@CHARTSCATTER( 'Title', 'X-Axis Label', 'Y-Axis Label', 'Legend1', X1, Y1[, ..., 'Legendn', Xn, Yn]);

Each scatter plot is represented by a list of (x,y) coordinates giving the location of each point in the scatter.  Multiple scatter plots can be displayed in a single chart, with each being in a different color.

Spacetime

@CHARTSPACETIME( 'Title',  'X-Axis Label', 'Y-Axis Label', 'Legend1', ARC1, TIME1, TIME2, [, ..., 'Legendn', ARCn, TIME1n, TIME2n]);

Spacetime charts are useful in visualizing the changes within a system over time, e.g., an airline's flights during some period of time.  Time is typically measured on the x-axis and there are arcs representing movements or changes within the system over time.

The ARC argument is a 3-dimensional set of arcs.  The first dimension is the arc label/name, the second dimension store the origination point, while the final dimension store the arc destination. TIME1 and TIME2 store the start and end times for each arc. Multiple spacetime series may be plotted on teh same chart.

The sample model CHARTSPACETIME is an example of a spacetime chart for an airline schedule. In this example, the cities in the schedule are listed on the y-axis, and each arc represents a scheduled flight.

Surface

@CHARTSURFACE( 'Title', 'X-Axis Label', 'Y-Axis Label', 'Z-Axis Label', 'Legend', X, Y, Z);

Each surface plot is represented by a list  of (x,y,z) coordinates, each containing the location of a points on the surface.   A sufficient number of points should be included to avoid excessive interpolation between points.  Only one surface may be drawn on a chart.  See the sample model CHARTSURF below for an example of a surface chart.

Tornado

@CHARTTORNADO( 'Title', 'X-Axis Label', 'Y-Axis Label', Base, 'Legend High', High, 'Legend Low', Low);

A tornado chart is represented by a list  of (high, low) pairs, giving the two extreme outcomes for a particular property (say profit) subject to changes in a particular parameter (say price). The base value is a single value for the property of interest given normal, or expected values, for each of the parameters. This is represented by one horizontal bar for each parameter, centered around the base value. The bars are then sorted by their lengths, giving the chart the appearance of a tornado. Tornado charts are useful for visualizing the sensitivity of a particular property to changes in a number of parameters. An example can be found in the LINGO sample models folder under the name ASTROCOSTRNDO.

As another example, we will show how to create a surface chart by supplying a grid of (x,y,z) points lying on the surface: z = x * sin( y) + y * sin( x) using the following model, CHARTSURF:

MODEL:

 

! Creates a surface chart of z = x * sin( y) + y * sin( x);

 

SETS:

 !Set up a 21x21 grid of (X,Y,Z) points on the surface;

 SURF1 /1..21/;

 SURF2( SURF1, SURF1): X, Y, Z;

ENDSETS

 

CALC:

 !First point;

 XS = @FLOOR( - (@SIZE( SURF1) / 2) + .5);

 YS = XS;

 

 !Generate remaining points and compute z;

 @FOR( SURF2( I, J):

   X( I, J) = XS + I - 1;

   Y( I, J) = YS + J - 1;

   Z( I, J) = X( I, J) * @SIN( Y( I, J)) + Y( I, J ) * @SIN( X( I, J));

 );

 

 !Create the chart;

 @CHARTSURFACE(

   'z = x * sin( y) + y * sin( x)',  !Title;

   'X', 'Y', 'Z',                    !Axis labels;

   '(X,Y,Z)',                        !Legend;

   X, Y, Z                           !Points on the surface;

 );

ENDCALC

 

END

Model: CHARTSURF

First off, the CHARTSURF creates a 21x21 grid of points on the (X,Y) plane centered around (0,0) and computes Z for each  of these points:

 !First point;

 XS = @FLOOR( - (@SIZE( SURF1) / 2) + .5);

 YS = XS;

 

 !Generate remaining points and compute z;

 @FOR( SURF2( I, J):

   X( I, J) = XS + I - 1;

   Y( I, J) = YS + J - 1;

   Z( I, J) = X( I, J) * @SIN( Y( I, J)) + Y( I, J ) * @SIN( X( I, J));

 );

We then use the @CHARTSURFACE function to create the surface chart:

 !Create the chart;

 @CHARTSURFACE(

   'z = x * sin( y) + y * sin( x)',  !Title;

   'X', 'Y', 'Z',                    !Axis labels;

   '(X,Y,Z)',                        !Legend;

   X, Y, Z                           !Points on the surface;

 );

The resulting chart will appear as follows:

chartsurf

Simplified Chart Function Formats

Some of  the chart functions above support a simplified format where all the arguments, with the exception of the data attributes, are omitted.  For instance, in the bar chart example above, we could have simply used the following:

  ! Bar chart of required vs. actual staffing;

  @CHARTBAR( REQUIRED, ONDUTY);

In which case, the resulting chart would be:

chartstaff2

Note the following differences between the charts created using the simplified chart format and the example above where we specified all the arguments:

The chart title is now the file name.
The legends are simply the names of the attributes.
The X and Y axis labels have been omitted.

The simplified syntax for each of the charting functions appears below:

Chart Type

Simplified Syntax

Bar

@CHARTBAR( Attribute1[, ..., Attributen]);

Bubble

@CHARTBUBBLE( X1, Y1, Size1,[, ..., Xn, Yn, Sizen]);

Contour

@CHARTCONTOUR( X, Y, Z);

Curve

@CHARTCURVE( X1, Y1[, ..., Xn, Yn]);

Histogram

@CHARTHISTO( X);

Line

@CHARTLINE( X1[, ..., Xn]);

Netarc

@CHARTNETARC( X1, Y1, X2, Y2[, ..., X1n, Y1n, X2n, Y2n]);

Netnode

@CHARTNETNODE( X1, Y1, I1, J1[, ..., Xn, Yn, In, Jn]);

Pie

@CHARTPIE( X);

Radar

@CHARTRADAR( X1[, ..., Xn]);

Scatter

@CHARTSCATTER( X1, Y1[, ..., Xn, Yn]);

Surface

@CHARTSURFACE( X, Y, Z);

Tornado

@CHARTTORNADO( Base, High, Low);

 

Using Procedures to Specify Chart Points

For curve, surface and contour charts, you may use a procedure to specify the function to be plotted.  LINGO will automatically call this procedure to generate function points for the chart, thereby allowing you to skip the step of explicitly generating the points.  The syntax for these procedure based charting functions is as follows:

Chart Type

Syntax

Contour

@CHARTPCONTOUR(  'Title', 'X-Axis Label', 'Y-Axis Label', 'Z-Axis Label', PROCEDURE, X, XL, XU, Y, YL, YU, 'Legend', Z);

Curve

@CHARTPCURVE(  'Title', 'X-Axis Label', 'Y-Axis Label', PROCEDURE, X, XL, XU, 'Legend1', Y1[, ...,'LegendN', YN]);

Surface

@CHARTPSURFACE(  'Title', 'X-Axis Label', 'Y-Axis Label', 'Z-Axis Label', PROCEDURE, X, XL, XU, Y, YL, YU, 'Legend', Z);

 

In the case of the two-dimensional curve chart, the PROCEDURE argument is the name of the procedure containing the formula for the curve, X is the independent variables, XL and XU its upper and lower bounds and Y1 is the dependent variable that gets assigned the function's value.  The three-dimensional contour and surface charts have two independent variables (X and Y) and the dependent variable Z.  As an example, the model below uses the @CHARTPSURFACE function to generate the same surface chart presented above:

MODEL:

 

! Creates surface chart of z = x * sin( y) + y * sin( x);

! Function points are provided by the WAVE procedure;

 

PROCEDURE WAVE:

  Z = X * @SIN( Y) + Y * @SIN( X);

ENDPROCEDURE

 

CALC:

  B = 10;

  @CHARTPSURFACE(

    'z = x * sin( y) + y * sin( x)', !Title;

    'X','Y','Z',  !Axis labels;

    WAVE,         !Procedure name;

    X, -B, B,     !Independent var 1 and its bounds;

    Y, -B, B,     !Independent var 2 and its bounds;

    'Z',          !Legend;

    Z             !Dependent var/function value;

  );

ENDCALC

 

END

Model: CHARTPSURF

Note: Charting capabilities are only available in the interactive versions of LINGO.  If you are using the LINGO API and need a charting capability, then you should investigate third-party solutions or use charting tools available in your development environment.