Anatomy of a Graph

How do we refer to graph objects and sub-objects when manipulating
them directly?

. anatomy0

. anatomy ado-file

Click on the anatomy0 link and look at the resulting graph. Two parts
of this graph have been labeled and those labels show how we refer to the two
parts of the graph. The title is called .Graph.title. Because we have
not named our graph using the name() option or the graph rename
command, our graph has the default name .Graph. A graph is a nested
object containing, among other things a title, and we refer to that title
within Graph by typing .Graph.title. Note that the leading dot
(.) is a required part of the name - all class system names begin
with a dot. Similar to the title, the graph's plotregion is referred to as
.Graph.plotregion1. The plotregion is numbered because it is possible
for a graph to have more than one plotregion.

Now, click on anatomy and let's look at a graph with more object's
labeled with their names. We can see that the title of the X-axis is nested
within the axis itself and is called .Graph.xaxis.title. The keys of a
legend are stored in an array and so the first key is referred to as
.Graph.legend.key[1]. The other components of the graph are named
similarly.

Also note that the title contains another object called .style, with the
full name .Graph.title.style. Almost all of the other objects also have
a .style object, and, indeed almost every object that can be drawn has a
.style. The style controls how an object looks and the vast majority of
options to the graph command do nothing more than set the values of the
objects contained in the .style.

Before going on, let's show that anatomy is nothing but an ado-file
that uses the line graph command to draw the graph we have just seen.
Click on ado-file above to see the contents of the
anatomy ado file. (Note, you will need to click the "Back" button on
the viewer to bring yourself back to this slide). Looking at the end of the
line command we see that additional options can be supplied to
anatomy and will be added to the options of the line
command.

Armed with this information, let's

1. Change the title to be huge and red using
options to line

2. Redraw the original graph with its small, black title

3. Edit the title style directly using a the .rows.smcl
program to make the title huge and red

2. Redisplay our graph to see that our edit had exactly the same
effect as using the options.

Do these steps by clicking the the four commands below in sequence. Be sure
to wait and examine the drawn graphs after steps 1, 2, and 4.

Some simple manipulations:

. anatomy title(, color(red) size(huge))

. anatomy

. .Graph.title.style.editstyle color(red) size(huge) editcopy

. graph display

Let's break down the 3rd line. We are clearly referring to the object
.Graph.title.style, but what is .editstyle? It is just a member
program that can be run on ANY style object. In this case, it is a
textboxstyle as documented in help textboxstyle.
The .editstyle program takes arguments and among those arguments are
stylename(style) arguments to set the values of the styles nested
within a textboxstyle. Specifically, we set the .color to be
red and the .size to be huge.

What does the editcopy argument do?

Let's see by example. For the remainder of our examples, we will move to a
slightly cleaner version of the anatomy graph - anatomy1. Click the
following 3 commands. Note that our .editstyle, in this case, is
operating on the X-axis style and that we are trying to change the axis labels
to be large and red. The axis style is deeply nested and we can
see that in the nested argument to .editstyle.

. anatomy1

. .Graph.xaxis1.style.editstyle majorstyle(tickstyle(textstyle( color(red) size(large) )))

. graph display

That isn't exactly what we wanted. Instead of changing just the look of the
X-axis labels, we also changed the Y-axis labels. In some cases, that might
be a good thing, but it is not what we set out to do.

What has happened is that we edited the base definition of a default axis
style, and since both the X- and Y-axes were using this default axis style,
they were both affected by our edit.

Moreover, what we did went even deeper than that. Let's redraw the graph from
the original command.

. anatomy1

Our large, red labels stuck.

What if we use a completely different dataset and draw a different type of
plot. Let's draw a simple scatter plot using the auto data by clicking the
following 2 commands in sequence.

. sysuse auto

. scatter mpg weight

Wow! We didn't ask for any options on our new scatter plot, yet it picked up
our edit of the graph we drew earlier. This occurs because our edit
changed the underlying definition of a default axis.

Again, this might be interesting and useful behaviour in some circumstances,
but it wasn't what we were trying to do.

Let's prove that edit wasn't permanent by discarding to clear the
graphics system and redrawing the anatomy graph.

. discard

. anatomy1

Whew! Finally things are back to normal.

Now, let's apply the same edit, only including the editcopy argument.

. .Graph.xaxis1.style.editstyle majorstyle(tickstyle(textstyle( color(red) size(large) ))) editcopy

. graph display

That is what we were after. By using editcopy we made a copy of the
style local to the X-axis before setting the text to be large and red. Our
edit now affects only this X-axis on this graph.

Plot types are (usually) just style settings

You might be surprised to learn that the type of a plot, line,
scatter, bar, etc., is usually determined simply by a style
setting. Our first plot is currently a line plot. What if we use
.editstyle to change its .type to area? (Click the
following two commands.)

. .Graph.plotregion1.plot1.type.editstyle area

. graph display

The first plot now renders as an area.

Setting how twoway plots look

Because so many things can be done with the look of plots and because they are
the backbone of twoway graphs, we should probably see how to change the
look of a plot. Let's change the fill color of our new area plot.

. .Graph.plotregion1.plot1.style.editstyle area(shadestyle(color(green))) editcopy

. graph display

Perfect.

That our plot is called plot1 within plotregion, .plotregion1 is
not surprising. Why though is our argument to .editstyle so nested?
Because the style of a plot is nested set of simpler styles. We have actually
changed the value of the the colorstyle -
.Graph.plotregion1.plot1.style.area.shadestyle.color and made it green.

If the styles are just nested, why didn't we choose to apply .editstyle
all the way down at the .color level, or somewhere else along the way?
Why did we apply .editstyle to the top-level style? The answer is
related to the reason we use the editcopy argument. If we applied our
.editstyle below the top-level .style, then we would only be
making a copy of that component style and not the entire pstyle.
Because no copy was made of the top-level style, we would again be making
changes to the default definition of the style and those changes would appear
in other graphs drawn using that style.

Saved graphs are a story

Let's look at one more aspect of graphs. Up until now, we have been playing a
little fast and loose with our edits and the following example will
demonstrate that. We have a nice edited graph, let's save that graph to disk
and restore it using by clicking on the following 3 commands (the
discard assures us that the graphics system has been cleared).

. graph save mygraph, replace

. discard

. graph use mygraph

Where did all of our nice edits go? We are back to the original
anatomy1 graph devoid of our edits. Our edits were lost because we only
changed the underlying graph objects, we did not tell the graph to record our
changes so that the would be saved with the graph. Among other things,
recording these changes is what makes it feasible to "re-scheme" a graph when
it is graph used with the scheme() option.

I should note, we could have printed, exported, or saved and restored this as
an asis graph and things would have gone fine. All of these processes
rely strictly on the objects created by the graph and do not require that the
graph record the edits required to recreate or edit those objects.

How then do we record our edits? At the lowest level, recording edits is
actually quite involved because the edits must be recorded with the correct
object. Imagine two graphs drawn on different schemes each with some options
to change the look of a title or a plot. Now these graphs are
graph combined and during that combine the look of the title of the
combined graph was changed. Where the edits are recorded can be tricky.

Luckily for us, that intricacy can be hidden, and all we need do is prefix our
edit commands with the support program _gm_edit. That program
determines where our edit needs to be recorded and makes sure that our edit is
both made and recorded.

Let's redraw the graph and reapply our edits; this time including
the _gm_edit prefix. (Click the next four commands).

. anatomy1

. _gm_edit .Graph.plotregion1.plot1.type.editstyle area

. _gm_edit .Graph.plotregion1.plot1.style.editstyle area(shadestyle(color(green)))

. graph display

Now, let's save and restore our edited graph. (Click the next 3 commands.)

. graph save mygraph, replace

. discard

. graph use mygraph

That did it.

<< index >>