Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Modify barlabel and yaxis on hbar graph

    Hi Stata Users,

    I'm using a graph hbar to make a graph that illustrates results from a difference-in-differences estimation. I'm using the auto data set to illustrate. In the example, I estimate the car price as a function of an indicator for foreign and for a large car. I'm saving the estimated means and standard errors using lincom. Then I make one plot for domestic cars, one for foreign cars and one for the difference. Each plot has the same principle:

    I'm plotting 3 horizontal bars, one for small cars, one for large cars and one showing the difference. Each bar has a label giving the estimated mean for each group (i.e. the height of the bar). I want to make two modifications:

    1. I want to add a second bar label that gives the estimated standard error (saved as variables se_*). This should be displayed under the mean in parentheses. How can I add this? I saw the advice of combining a scatterplot with a twoway bar. But this doesn't work here, since scatter does not allow the option "horizontal". I want a horizontal bar chart to illustrate the difference-in-difference by combining all three plots.

    2. I want to move the horizontal axis (y-axis in the hbargraph) up along the vertical axis, such that it runs between the bar for large and the difference.

    Here is my code using the auto data set for illustration:

    Code:
    sysuse auto, clear
    gen large = weight>3000
    gen foreign_large = foreign* large
    
    *Diff-in-diff regression
    
    reg price large foreign foreign_large
    
    *Calculate means and standard errors for domestic cars:
        *small
        lincom _cons
        gen  mean_small_dom = r(estimate)
        gen se_small_dom=r(se)
        
        *large
        lincom _cons +large
        gen  mean_large_dom = r(estimate)
        gen se_large_dom =r(se)
        
    
        *difference
        lincom -large
        gen diff_small_large_dom = r(estimate)
        gen se_small_large_dom = r(se)
        
        keep mean* se* diff*
        duplicates drop
        
        
    *Make graph
        graph hbar mean_small_dom mean_large_dom diff_small_large_dom , ///
        bargap(5) blabel(bar ,pos(outside) format(%5.2f) color(black) size(medium)) ///
        showyvars yvaroptions(relabel (1 "Small" 2 "Large" 3 "Difference")) ///
        legend(off) ///
        title("Average Price by Size and Origin - Domestic Cars") ///
        yscale(range(-5000 (1000) 9000)) ylabel(-4000 (2000) 8000)
    Thanks in advance!

  • #2
    If you want to use graph hbar to accomplish this these might work:
    (1) edit the graph manually with the graph editor (works fine if you have one graph that you need to produce only one time)
    (2) use a hackish approach like undocumented " .plotregion1.barlabels[3].text.Arrpush XX " types of commands (see: https://www.stata.com/statalist/arch.../msg01386.html ) (warning this method is slower if you are producing many graphs, or
    (3) use textbox() to place text at coordinates on the graph.

    I tend to use (3) if I need to use -graph bar- but where possible I use -twoway- horizontal bar plots like the example below. This approach is convoluted , but I find it to be more loopable when I'm doing something with a series of graphs since the location of the labels is anchored to the end of the bar in some way rather than trying to calculate the positioning of the label that I'd need to feed to textbox().

    Code:
    **updating your code example:
    sysuse auto, clear
    gen large = weight>3000
    gen foreign_large = foreign* large
    
    *Diff-in-diff regression
    
    reg price large foreign foreign_large
    
    *Calculate means and standard errors for domestic cars:
        *small
        lincom _cons
        gen  mean_small_dom = r(estimate)
        gen se_small_dom=r(se)
        
        *large
        lincom _cons +large
        gen  mean_large_dom = r(estimate)
        gen se_large_dom =r(se)
        
    
        *difference
        lincom -large
        gen diff_small_large_dom = r(estimate)
        gen se_small_large_dom = r(se)
        
        keep mean* se* diff*
        **duplicates drop
        keep in 1/3
        g i = _N-_n
        
        
    *Make graph
        graph hbar mean_small_dom mean_large_dom diff_small_large_dom if i==1, ///
        bargap(5) blabel(bar ,pos(outside) format(%5.2f) color(black) size(medium)) ///
        showyvars yvaroptions(relabel (1 "Small" 2 "Large" 3 "Difference")) ///
        legend(off) ///
        title("Average Price by Size and Origin - Domestic Cars") ///
        yscale(range(-5000 (1000) 9000)) ylabel(-4000 (2000) 8000)  
        
        
        
        lab def yval 0 "Diff" 1 "large" 2 "small", modify
        lab val i yval
    
        /*  I attempted to insert a ascii line break to get the label to wrap - this failed as Stata ignores the second line....
        g lab = string(mean_small_dom) + `"`=char(13)'"' + "("+ string(se_small_dom)+")" if i ==2
        replace lab = string(mean_large_dom) + `"`=char(13)'"' + "("+ string(se_large_dom)+")" if i ==1
        replace lab = string(diff_small_large_dom) + `"`=char(13)'"' + "("+ string(se_small_large)+")" if i ==0
        ta lab
        */
    
    
    
        g lab1 = ""
        g lab2 = ""
        replace lab1 = string(mean_small_dom)  if i ==2
        replace lab1 = string(mean_large_dom)  if i ==1
        replace lab1 = string(diff_small_large_dom)   if i ==0    
        replace lab2 =  " ("+ string(se_small_dom)+")"  if i ==2
        replace lab2 = " ("+ string(se_large_dom)+")"  if i ==1
        replace lab2 =  "   ("+ string(se_small_large)+")"   if i ==0    
        cap drop diff_small_large_dom2 //adjust label left
        g diff_small_large_dom2 = diff_small_large_dom-800 if i==0
        
    twoway bar mean_small_dom i if i==2, horizontal || ///
         bar mean_large_dom i if i==1, horizontal || ///
         bar diff_small_large_dom i if i==0, horizontal ||  /// 
        scatter i mean_small_dom if i ==2, msym(non) mlab(mean_small_dom) mcolor(none) mlab(lab1) mlabsize(small) mlabpos(1) ||  ///
        scatter i mean_large_dom if i ==1, msym(non) mlab(mean_small_dom) mcolor(none) mlab(lab1)  mlabsize(small) mlabpos(1)  ||  ///
        scatter i diff_small_large_dom2 if i ==0, msym(non) mlab(mean_small_dom) mcolor(none)  mlab(lab1)  mlabsize(small) mlabpos(11.5)  mlabgap(3)   ||  ///
        scatter i mean_small_dom if i ==2, msym(non) mlab(mean_small_dom) mcolor(none) mlab(lab2)  mlabsize(small) mlabpos(3)  ||  ///
        scatter i mean_large_dom if i ==1, msym(non) mlab(mean_small_dom) mcolor(none) mlab(lab2)  mlabsize(small) mlabpos(3)  ||  ///
        scatter i diff_small_large_dom2  if i ==0, msym(non) mlab(mean_small_dom) mcolor(none) mlab(lab2)  mlabsize(small) mlabpos(9.5) mlabgap(0)  ||  ///
       , xline(0, lwidth(thick))  legend(off) ///
        title("Average Price by Size and Origin - Domestic Cars") ///
        xscale(range(-5000 (1000) 9000)) xlabel(-4000 (2000) 8000)  /// 
        ylab(0(1)2, labels valuelabel)  yscale(lwidth(none) lcolor(none))

    produces this graph (with my default scheme)

    Click image for larger version

Name:	graph.png
Views:	1
Size:	162.7 KB
ID:	1437208
    Eric A. Booth | Senior Director of Research | Far Harbor | Austin TX

    Comment


    • #3
      how do I have a common y-label instead of suppressing all. I want the race to be displayed only in the first graph.

      use http://www.stata-press.com/data/r14/nlswork

      graph hbar tenure hours wks_work if age < 16, ///
      over(race, label(labstyle()) ) ///
      by(age, style(combine) row(1) norescale edgelabel iylabel noiytitle iytick noiyaxes) ///
      legend(label (1 "tenure") label (2 "hours") label (3 "wks_work") row(1)) ///
      ysize(2) name(a, replace)
      Click image for larger version

Name:	aa.png
Views:	4
Size:	73.0 KB
ID:	1641824

      Comment


      • #4
        #3 is a duplicate post. See https://www.statalist.org/forums/for...-x-axis-labels for comment.

        Comment

        Working...
        X