Recursively building graph commands

March 8, 2012 at 9:56 am 2 comments

| Gabriel |

I really like multi-line graphs and scatterplots where the marker color/style reflects categories. Such graphs are both more compact than just having multiple graphs and they make it easier to compare different things. The way you do this is with “twoway,” a lot of parentheses, and the “if” condition. For example:

twoway (kdensity x if year==1985) (kdensity x if year==1990) (kdensity x if year==1995) (kdensity x if year==2000) (kdensity x if year==2005), legend(order(1 "1985" 2 "1990" 3 "1995" 4 "2000" 5 "2005"))

Unfortunately such graphs can be difficult to script. This is especially so for the legends, which by default show the variable name rather than the selection criteria. I handle this by recursively looping over a local, which in the case of the legend involves embedded quote marks.

capture program drop multigraph
program define multigraph
	local var         `1'
	local interval	  `2'

	local command ""
	local legend ""
	local legendtick=1
	forvalues i=1985(`interval')2005 {
		local command "`command' (kdensity `var' if year==`i')"
		local legend `legend' `legendtick' `" `i' "'
		*"
		local legendtick=`legendtick'+1
	}
	disp "twoway ""`command'" ", legend:" "`legend'"
	twoway `command' , legend(order(`legend'))
end

To replicate the hard-coded command above, you’d call it like this:

multigraph x 5
About these ads

Entry filed under: Uncategorized. Tags: , , .

Bleg on Failure Control for x

2 Comments

  • 1. Eric  |  March 8, 2012 at 11:12 am

    Good tip. Earlier this week I was trying to convince some students about the benefits of recursively building the contents of the “cells()” option in a -tabout- command when looping over lots of vars and making summary tables.

    ***
    Just to add to your example of graph automation…
    I like to use the macro extended functions to automatically add the titles, notes, etc based on a variable’s characteristics in graph or table commands, e.g.,

    ************Example
    clear
    **make some fake data:
    set obs 100000
    g year = 1985 + round(runiform()*20, 5)
    g x = runiform()*100
    lab var year "Year"
    lab var x "Something Interesting"
    **
    
    
    
    capture program drop multigraph
    program define multigraph
    	local var   `1'    //note, you could just use '1'/'2' below
    	local interval  `2'
    
    	local command ""
    	local legend ""
    	local legendtick=1
    	forvalues i=1985(`interval')2005 {
    		local command "`command' (kdensity `var' if year==`i')"
    		local legend `legend' `legendtick' `" `i' "'
    		*"
     local legendtick=`legendtick'+1   
    
      *!  note, you can also iterate this with the expansion_optr ++, like:
     **  loc legendtick `++legendtick'
    
         }
    	disp "twoway ""`command'" ", legend:" "`legend'"
    	twoway `command' , legend(order(`legend') colfirst /*added for reordering the legend*/ )  ///
    		title(`"KDensity plot for {bf:`:var l `var''}"') ytit(`"{it:`:var l year'}"')
    end
    
    
    multigraph x 5
    
    *************

    [Note: Gabriel added "pre" html tags for formatting]


The Culture Geeks

Recent Posts


Follow

Get every new post delivered to your Inbox.

Join 1,472 other followers

%d bloggers like this: