*! Help file for version 1.6 of isoplot.ado, by Mead Over (mover@cgdev.org) 6Oct2016

Title

isoplot -- Portray the contours (or isoquants) of
a three-dimensional surface by superimposing scatterplots.
Faster alternative to Stata's contourline

Syntax

isoplot yaxisvar xaxisvar [if] [in]
[, options]

Options

Required
isovar(zaxisvar) Name of the z-axis variable, for values of which
isoplot will draw contour lines in the positive quadrant of the plane spanned by (yaxisvar, xaxisvar).
A required option.

centiles|values Select whether the contours plotted
are defined by specific values of isovar or by centiles of its distribution.
The user is required to specify one of these
two options, but may not specify both.

ccuts(numlist) List of numbers which determines
the values of -isovar- at which level sets (or contours) will be plotted.
With the -centiles- option, these are percentiles of the -isovar- istribution.
With the option -values-, these are the user-selected values of -isovar-.
A required option.

Optional: Contour options
tolerance(tol) The width of the bands of plotted points.
Default is 1.0.
With the option -centiles-, the bands of plotted points
are within a multiple -tol- of the difference between the upper and lower
bounds of the estimated centiles.
With the option -values-, the bands of plotted points
are within -tol- percent of the selected value.

lowess Display a line fitted to each contour
by the non-parametric lowess command.

bwidth Bandwidth for the lowess line graphs. See lowess
and the associated manual entry for an explanation of the term bandwidth
in the context of lowess smoothing. The default value here in
isoplot is 0.1.

lwidth Width of the line used in lowess plots.

contour Superimpose a contourline constructed by Stata's
contourline command. With this option
isoplot allows only a single value of ccuts().
To display a solid line fitted to each of several contours,
use the lowess option.

noscatter Suppress the scatterplots. For use when
option lowess or contour is selected.

Optional: Cost function options
plotjoint(stat) Plot the output combination
representing joint production within a single firm (or plant or
or other production unit) of the stat amount of the two
outputs represented on axes x and y.

plotspec(stat) Plot the two output combinations representing the
(quasi-) specialized production of the two outputs, each in a specialized firm.
Combinations plotted will be [e*Y1_m, (1-e)*Y2_m]
and at [(1-e)*Y1_m, e*Y2_m], where -m- denotes the -stat- selected by the
plotspec(stat) option and e is defined by its own option epsilon(e)
and represents the fraction of each output produced by the NON-specialized firm.
The term "quasi-specialized" is due to
Pulley and Humphrey (1991) and Pulley and Braunstein (1992), who
used it to define a generalized measure of economies of scope called "QSCOPE".
See qscope for details and an algorithm to compute the
economies of scope for a previously estimated cost function.

epsilon(e) The fraction of each output produced by the
NON-specialized firm. This option is only relevant if the option plotspec(stat)
is also selected. With the default value of e = 0, the plotspec(stat)
option positions one of the two firms on each of the two axes.
As e increases from zero to 1/K (where K is the total number of outputs),
the positions of the two firms move towards one another in the two-dimensional
plane formed by the variables yaxisvar and xaxisvar.
Plotting these two firms is useful for illustrating the computation of
Pulley and Humphrey's (1991) concept of quasi-economies of scope.

function(y=f1(x)) Overlay a line graph of an arbitrary function
of yaxisvar as a function of xaxisvar.
Specify the function by writing y = f1(x),
where the syntax is the same as in Stata's
twoway function. If isoplot is
used to present a cost function, one use for this option might be
to overlay an expansion path.

function2(y=f2(x)) Overlay a graph of a second arbitrary
function. If the objective is to define a region of output combinations
with an elliptical shape, option function(y=f1(x)) might draw the
top of the ellipse, while option function2(y=f2(x)) draws the bottom.

Optional: Legend options
lgndtitle(string) Specify the legend's title.

lgndsub(string) Specify the legend's subtitle.

legend(off) Suppress the legend.

Optional: Other options
* Any other -graph twoway- options. If user specifies a
legend option, it overrides the default legend.

Description

isoplot constructs scatterplots which define projections
of a three-dimensional surface onto a two-dimensional plane.
In various applications these projections are referred to as contours,
level sets, isoquants, isoclines, isocost curves or production possibility frontiers.
Given observations on three variables, (Xi,Yi,Zi), for i = 1,2 ...,N,
the command:

isoplot Y X, isovar(Z) ccuts(25 50 75) centiles

plots a scatterplot which defines each of three contours,
one each for the 25th, the 50th and the 75th centile of Z.
The scatterplot contour for the 25th percentile of Z
is constructed by selecting and plotting only those observations
for which Z lies within a specified tolerance of its 25th centile.
The same procedure plots the points close to Z's 50th and 75th percentiles.
isoplot can be applied to simulated data as in the example below.
isoplot can also be used as a
postestimation command. For example, the user might
estimate a multi-output cost function, Z = f(Y1,Y2), and then compute
the predicted cost,
Z_hat, at specified values of Y1, Y2.
isoplot can portray the contours of the estimated function
by substituting the predicted variable Z_hat for Z
in isovar(zaxisvar) option of the above command.

Discussion

This command, isoplot, can be viewed as a complement to, or as a substitute for,
Stata's contourline command. Because isoplot
displays the observations for which the zaxisvar is within a tolerance of
a specified value, one might prefer to execute isoplot prior to
contourline on the same values of ccuts().
However when the number of observations is larger than a few hundred,
isoplot's speed advantage over contourline is pronounced.
For example, using Stata/SE on a Windows OS PC, powered by a 3.4 GHz Intel i7-3770 CPU
with 16 GB of RAM, the commands isoplot and contourline
require the following execution times as a function of the number of observations:

+----------------------------+
| Seconds required to draw |
| 2 contours by |
| number of observations: |
+----------------------------+
| N isoplot contourline|
|----------------------------|
1. | 50 .297 .469 |
2. | 100 .297 1.015 |
3. | 200 .297 4.86 |
4. | 400 .328 28.029 |
5. | 800 .344 160.973 |
|----------------------------|
6. | 1000 .344 263.268 |
7. | 1600 .329 688.733 |
8. | 3200 .375 2106.16 |
+----------------------------+

The time required by a single-processor version of Stata to construct contours using
contourline thus rises faster than the square of the
number of observations. With a sample size of 10,000, such as that used in the examples
below, the estimated time to complete a single execution of contourline
is between 4 and 8 days. isoplot requires less than half a second.
(I suspect that with Stata/MP contourline would
scale much more efficiently with the number of observations.)

isoplot is designed for constructing scatterplot contours in the positive
orthant as is required in microeconomic applications where the zaxisvar
is, for example, total cost and the xaxisvar and
the yaxisvar variables are two of the outputs of a multi-output firm.
All three of these variables are typically defined to be non-negative.
Therefore isoplot might have difficulty constructing plots outside the
positive orthant.

Several of isoplot's capabilities are specifically suited to post-estimation
analysis of an estimated multiple-output cost function, as in the examples below.
However, isoplot could also be useful for post-estimation analysis
of a production function in order to limn the contours of isoquants, for example.

Examples

Setup: Generate cost function data

In order to demonstrate isoplot's capabilities, we first generate
a simulated sample of cost function data. We assume that the true total cost
of production is a function of the amounts of each of two outputs, y1 and
y2, and of a factor price, w (think wage). In a real-world
sample the amounts produced of the two outputs might be either positively
correlated (if larger firms produce more of both outputs) or negatively
correlated (if firms tend to specialize in one or the other). The first
sample we generate adopts the neutral view that the outputs are uncorrelated
in the population from which the sample is drawn. Furthermore, we assume
that the the marginal distributions of y1 and y2 are uniform
so that the sample of output combinations (y1, y2) evenly fills the positive
quadrant of combinations. (Our approach follows Gould (19??), but omits the
invnormal() transformation.)

Having generated the determinants of total cost, we simulate the true and the
observed values of total cost by positing a joint cost function with
strong economies of scope. We generate the variable true using
a functional form which is a generalization of the equation
for a two-dimensional ellipse.

gen true = ($alpha*(y2^$beta + y1^$beta)^($s/$beta)) + $gamma * lnw

Note that if the parameter $beta were negative, and the variables true,
y1 and y2 represented output and two factors of production,
the above functional form would be the classic "Constant Elasticity of Substitution"
(CES) production function originally proposed by Arrow, Chenery, Minhas and Solow (1961).

We then generate observed cost by multiplying true by
a uniformly distributed disturbance term:

gen observed = true * exp($sigma*uniform())

For this first example, we execute the program isopolot_example with
the argument cost_dgp, which invokes the default variables of
all the parameters. These are:

n = 10,000 : Number of observations in the simulated data set

rho = 0 : Correlation coefficient between y1 and y2

alpha = 100 : Intercept parameter

beta = 3 : Complementarity parameter

scale = 1 : Scale elasticity parameter

gamma = 1 : Elasticty of cost w.r.t. the factor price, w.

sigma = 0.2 : Scale the variance of the disturbance term, w

seed = 54321 : Seed for random number generation
(Default is uniform distribution for determinants and disturbance term.
Specifying the option normal selects joint truncated normal distributions
of the determinants and a normal distribution of the disturbance.

To generate the two-output cost data with the above default parameters,
first clear Stata and then click on one of the following four
options:

click to set up the simulated cost data.

click to set up with rho = 0.25.

click to set up with joint normal distribution.

click to set up with rho = 0.25 and a joint normal distribution.

(Note that executing the program isoplot_example
with the arguments cost_dgp, rho(.25)
would allow replication of these examples with positively correlated outputs.)

Example 1: Display four isocost frontiers

This first demonstration of isoplot uses the data generated during by above setup
code. Click here to see the isocost frontiers for the 10th, 20th, 50th and 90th
centiles of the "true" cost data. The points of equal cost are tightly banded
around a convex contour because the variable "true" contains no disturbance term
and because we have assumed that factor prices contribute little to the
determination of total cost. The command is:

isoplot y2 y1, isovar(true) centiles ccuts(10 20 50 90)

(click to run Example 1)

Example 2: Isocost "bands" are wider with a disturbance term

Executing the same isoplot command on the "observed" cost data shows
how the frontiers appear when the two output variables, yaxisvar and xaxisvar,
explain a smaller part of the variation of the dependent variable.
The command is:

isoplot y2 y1, isovar(observed) centiles ccuts(10 20 50 90)

(click to run Example 2)

Example 3: Display the frontier for the cost of jointly producing median outputs

This example demonstrates that, with the values option,
isoplot can plot an isocost frontier
for any value of the isovar(zaxisvar) variable.
Here we select the value of the zaxisvar,
which the cost function predicts would be the cost of producing the
median level of both outputs, yaxisvar and xaxisvar,
at the median level of factor prices. By also selecting the
plotjoint(median) option, the observations with total costs
approximately equal to that of a firm producing median output levels
are also plotted, defining the isocost frontier for this cost level.
The command is:

isoplot y2 y1, isovar(true) plotjoint(median) values ccuts($cost_of_jnt)

where the global macro, $cost_of_jnt, has previously been computed.

(click to run Example 3)

Example 4: Compare the isocost frontiers for joint and specialized production

In the plane spanned by the two output variables, y1 and y2,
specialized production is represetned by a point on one of the two output axes.
In this example, we use the cost function to compute the cost of producing
the median amount of each output in a specializeed firm. Then we use isoplot
to plot these two firms along with the firm which is jointly producing
the median amounts of both outputs. By using the values option,
we then superimpose an isocost frontier at a level of cost corresponding
to the total cost of each of these three firms.

When the value of
the complementarity coefficient in the cost function is large and positive
as it is for our default assumptions in these examples, where $beta is 3.0,
the isocost frontiers for the specialized firms show that either specialized
firm could expand its production of the other output at little additional cost.
The command is:

isoplot y2 y1, isovar(true) plotspec(median) plotjoint(median) values ccuts($cost_of_y1 $cost_of_y2 $cost_of_jnt )

(click to run Example 4)

Example 5: Show cost savings from joint production

One way to represent the economies of
scope associated with this postulated cost function is to show how much
more output can be achieved through joint production for the same cost
as would be required to produce the same output in two specialized firms.
This example reproduces the graph from
Example 4 and then adds a fourth isocost contour. The fourth contour is a plot
of all the output combinations in the simulated data for which the cost of
jointly producing the two outputs is approximately the same as the sum
of the costs of the two specialized firms.
The command is:

isoplot y2 y1, isovar(true) plotspec(median) plotjoint(median) values ccuts($cost_of_y1 $cost_of_y2 $ $)

(click to run Example 5)

Stored Results

isoplot is a graphing routine. It accepts the standard
graph twoway options for naming and saving graphs.
Otherwise isoplot stores no results. See qscore for a program that estimates the
economies of scope observed in an isoplot graph.

References

Arrow, K.J., H.B. Chenery, B.S. Minhas, R.M. Solow (1961)
"Capital-labor substitution and economic efficiency,"
Rev. of Econ. & Stat.

Baumol, W.J., Panzar, J. and Willig, R. (1982).
Contestable markets and the theory of industrial structure.
Harcout Brace Javanovich Ltd., New York.

Gould, William (19??). "Stata 6: How can I simulate random multivariate
normal observations from a given correlation matrix?," Stata Corporation,
FAQs

Pulley, L. B., & Humphrey, D. B. (1991). "Scope economies: Fixed costs,
complementarity, and functional form".
Federal Reserve Bank of Richmond Working Paper, (91-3).

Pulley, L. B. and Y. M. Braunstein (1992). "A composite cost function for
multiproduct firms with an application to economies of scope in banking",
Review of Economics and Statistics, 74(2), 221-30.

Authors

Contact Mead Over at:
Email: MOver@CGDev.Org if you observe any
problems.