Statalist


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: st: Re: area between reference lines


From   "Nick Cox" <[email protected]>
To   <[email protected]>
Subject   RE: st: Re: area between reference lines
Date   Tue, 11 Nov 2008 22:16:28 -0000

Good tweak! NJC 

-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Steichen,
Thomas J.
Sent: 11 November 2008 22:09
To: '[email protected]'
Subject: RE: st: Re: area between reference lines


An interesting (and perhaps unacceptable) side-effect of Nick's
recasting of the variable to a scatteri/area is that the y-range was
expanded down to include 30 years. What happened is that Stata's "nice
tic" processor saw the lower value defined by `min' in the -scatteri-
command (which was 4% lower than the minimum defined by the data in the
-line- commands) and re-ranged the plot to include even more on the low
end than the -yscale(yrange(`min' `max'))- option asked for, thus making
this option superfluous (on the minimum side).

However, if Nick had specified the -scatteri- as:

(scatteri `max' 1915 `max' 1921, recast(area) col(emidblue*.25))

rather than

(scatteri `min' 1915 `max' 1915 `max' 1921 `min' 1921, recast(area)
col(emidblue*.25))

the "nice tic" processor would not have seen `min' and would not have
expanded the range (so -yscale(yrange(`min' `max'))- would have
controlled the range expansion). In fact, -recast(area)- ignores the low
corners of the -scatteri- and draws to the baseline, so there is no
advantage to specifying the lower corners.

Thus the code (with a cosmetic tweak on the x-axis) becomes:

sysuse uslifeexp, clear
* range y variables and set buffer
summ le_male, meanonly
local min = r(min)
local max = r(max)
sum le_female, meanonly
local min  = min(`min', r(min))
local max  = max(`max', r(max))
local buff = (`max' - `min') * 0.04
local min  = `min' - `buff'
local max  = `max' + `buff'
* do plot
tw (scatteri `max' 1915 `max' 1921, recast(area) col(emidblue*.25)) ///
   (line le_female year) (line le_male year) ///
   (scatteri 80 1921 "WW-I & " 78 1921 "Spanish Flu" 80 1945 "Post
WW-II", s(i)) ///
   , legend(order(2 "males" 3 "females") ring(0) pos(4) col(1)) ///
   xtitle("") ytitle("life expectancy (years)") yla(, ang(h)) ///
   xli(1945, lcol(emidblue*.5)) plotr(m(zero)) ///
   yscale(range(`min' `max')) xsca(ran(1898 2002))

Tom

-----------------------------------
Thomas J. Steichen
[email protected]
-----------------------------------

-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Nick Cox
Sent: Tuesday, November 11, 2008 1:58 PM
To: [email protected]
Subject: RE: st: Re: area between reference lines

Tom gave an elegant solution.

Here is a slightly different way of doing it: not really better, just
different.

You could use -scatteri-, giving the four corners of the rectangular
band, and then -recast(area)-.

That avoids the creation of a temporary variable.

The code below includes various extra cosmetic tweaks.

sysuse uslifeexp, clear
* range y variables and set buffer
summ le_male, meanonly
local min = r(min)
local max = r(max)
sum le_female, meanonly
local min = min(`min', r(min))
local max = max(`max', r(max))
local buff = (`max'-`min') * 0.04
local min = `min' - `buff'
local max = `max' + `buff'
* do plot
tw (scatteri `min' 1915 `max' 1915 `max' 1921 `min' 1921, recast(area)
col(emidblue*.25)) ///
   (line le_female year) (line le_male year) ///
   (scatteri 80 1921 "WW-I & " 78 1921 "Spanish Flu" 80 1945 "Post
WW-II", s(i)) ///
   , legend(order(2 "males" 3 "females") ring(0) pos(4) col(1))
///
   xtitle("") ytitle("life expectancy (years)") yla(, ang(h)) ///
   xli(1945, lcol(emidblue*.5)) plotr(m(zero)) yscale(range(`min'
`max'))

Steichen, Thomas J.

One possibility is to creat the "buffer" yourself. Here I place a 4%
buffer on the y-axis using yscale(range()) and some pre-calculations (if
desired, one could do something similar for the x-axis). My preference
is for subtle shading (as shown) but many other preferences exist.

sysuse uslifeexp, clear
* range y variables and set buffer
qui summ le_male
local min = r(min)
local max = r(max)
qui sum le_female
local min = min(`min', r(min))
local max = max(`max', r(max))
local buff = (`max'-`min') * 0.04
local min = `min' - `buff'
local max = `max' + `buff'
* do plot
tempvar aux
g `aux'=`max'
tw (area `aux' year if year>=1915 & year<=1921, col(emidblue*.25)) ///
   (line le_female year) (line le_male year) ///
   (scatteri 80 1921 "WW-I & " 78 1921 "Spanish Flu" 80 1945 "Post
WW-II", s(i)) ///
   , legend(order(2 3)) xli(1945, lcol(emidblue*.5)) plotr(m(zero))
yscale(range(`min' `max'))

Michael Hanson

Thanks, Tom: -plotregion(margin(zero))- is a useful option to know --
I would not have found it without your suggestion.  However, in
testing it, I noticed that forcing the margins of all graphs to zero
(which it must do to preserve the y-axis range) can have undesirable
side effects.  For example, if you replicate Martin's earlier example
with this option, the line graph will touch the x-axis in 1918.
There are circumstances where this behavior would be fine, but others
in which it would not -- and I prefer the default behavior of Stata
to "buffer away" the lower limit of the line graph from the axis in
this case.

Thus, I still find my "hack" of using a large range of dates within a
-tline- command to be preferable.  I still would like to see
StataCorp modify -tline- to accept a date range rather than a list of
individual dates, as this option would make my "hack" a little
cleaner and easier to use.

On Nov 10, 2008, at 8:53 AM, Steichen, Thomas J. wrote:

>  Try adding option -plotr(m(zero))- to your plot. This will remove
> the gap.


*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2024 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index