Announcement

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

  • Bar graph over two groups with error bars

    Hello,
    I know this topic has been revisited a number of times, but I have not seen a post that directly pertains to my issue. I want to graph means of a variable by two group vars: _m1 (=0 or 1) and _at2 (=1, 2, 3, 4, and 5). I want different colors for each value of _m1 and for each value of _at2, and I would like error bars on each. So, for example, when _m1 = 0 & _at2 = 1, bar is light green (or some other color, doesn't matter). When _m1 = 1 & _at2=1, bar is dark green. When _m1=0 & _at2=2, bar is light blue. When _m1=1 & _at2=2, bar is dark blue. Etc. I can come close on my own (see below), but I can't get different colors within the _at2 grouping.

    I am aware of Nick Cox's stata article on this topic, but could not modify his coding correctly.

    Thank you in advance for your help.

    Christina


    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input float(_margin _ci_lb _ci_ub) byte(_m1 _at2)
    .17165226  .1622764 .18102813 0 1
    .13737509 .12999927 .14475092 1 1
    .13159028 .12701863 .13616194 0 2
    .10741683  .1047295 .11010417 1 2
     .1110694 .10828185 .11385693 0 3
    .09586595 .09464125 .09709065 1 3
     .0961303 .09410548  .0981551 0 4
    .09158577 .09042265  .0927489 1 4
    .09303544  .0894075 .09666338 0 5
    .09294365 .09141235 .09447495 1 5
    end
    label values _m1 marry
    label def marry 0 "Unmarried", modify
    label def marry 1 "Married", modify
    qui {
    gen varx = _m1+1 if _at2 == 1
    replace varx = _m1+4 if _at2 == 2
    replace varx = _m1+7 if _at2 == 3
    replace varx = _m1+10 if _at2 == 4
    replace varx = _m1+13 if _at2 == 5
    }

    twoway (bar _margin varx if _at2==1, bcolor(navy)) (bar _margin varx if _at2==2, bcolor(purple*.7)) (bar _margin varx if _at2==3, bcolor(green)) (bar _margin varx if _at2==4, bcolor(orange*1.3)) ///
    (bar _margin varx if _at2==5, bcolor(red*1.2)) (rcap _ci_lb _ci_ub varx, lcolor(black)), ///
    xlabel(1.5 "No HS" 4.5 "HS" 7.5 "Some col" 10.5 "BA" 13.5 ">= MA", labsize(medlarge) noticks) xscale(range(.8 15.3)) yscale(range(0.05 .25)) ylabel(0.05(.025).25) ///
    ytitle("Predicted value", size(medlarge)) xtitle("Education Level", size(medlarge)) legend(off) xsize(7)



  • #2
    I've written various pieces in theStata Journal and can't identify which paper you're alluding to. I am very keen on dissuading people from bars plus error bars, so any code I wrote is likely to have been for a different purpose.

    To get different colours, you need values to be in different variables. No other way to do it.

    Code:
    help separate 
    may help.

    Comment


    • #3
      The easiest way to modify your code is just to add some additional if statements separating the _m1 values:
      Code:
      twoway (bar _margin varx if _at2==1 & _m1 == 0, bcolor(navy)) (bar _margin varx if _at2==1 & _m1 == 1, bcolor(navy*.5)) ///
          (bar _margin varx if _at2==2 & _m1 == 0, bcolor(purple)) (bar _margin varx if _at2==2 & _m1 == 1, bcolor(purple*.5)) ///
          (bar _margin varx if _at2==3 & _m1 == 0, bcolor(green)) (bar _margin varx if _at2==3 & _m1 == 1, bcolor(green*.5)) ///
          (bar _margin varx if _at2==4 & _m1 == 0, bcolor(orange)) (bar _margin varx if _at2==4 & _m1 == 1, bcolor(orange*.5)) ///
          (bar _margin varx if _at2==5 & _m1 == 0, bcolor(red)) (bar _margin varx if _at2==5 & _m1 == 1, bcolor(red*.5))  ///
          (rcap _ci_lb _ci_ub varx, lcolor(black)), ///
          xlabel(1.5 "No HS" 4.5 "HS" 7.5 "Some col" 10.5 "BA" 13.5 ">= MA", labsize(medlarge) noticks) xscale(range(.8 15.3)) yscale(range(0.05 .25)) ylabel(0.05(.025).25) ///
          ytitle("Predicted value", size(medlarge)) xtitle("Education Level", size(medlarge)) legend(off) xsize(7)

      You might also consider abandoning the idea of different colors for different levels of education (which are somewhat superfluous because you've labeled the columns) for code that is shorter and cleaner.
      Code:
      twoway (bar _margin varx if _m1 == 0, bcolor(navy)) (bar _margin varx if _m1 == 1, bcolor(navy*.5)) ///
          (rcap _ci_lb _ci_ub varx, lcolor(black)), ///
          xlabel(1.5 "No HS" 4.5 "HS" 7.5 "Some col" 10.5 "BA" 13.5 ">= MA", labsize(medlarge) noticks) xscale(range(.8 15.3)) yscale(range(0.05 .25)) ylabel(0.05(.025).25) ///
          ytitle("Predicted value", size(medlarge)) xtitle("Education Level", size(medlarge)) legend(off) xsize(7)

      Comment


      • #4
        Thank you - I really like your second suggestion. But the first was good to know for future reference.

        Comment


        • #5
          I would suggest insisting on base(0) for any bars.

          Comment

          Working...
          X