Announcement

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

  • Bar Colors in Twoway Bar Graph

    Hello Statalist users,

    Using Stata 13.1, I am trying to create a bar chart with specific bars highlighted. However, most documentation I have looked at (help barlook_options & "Stata tip 102: Highlighting specific bars" by Nick Cox) explain how to do this with a single bar chart. I am working with a two way bar graph to create a population pyramid and cannot figure out where to put the
    Code:
    bar(1, color(ltkhaki))
    in the code.

    Here is an excerpt of my data:
    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input int YEAR byte agegrp str9 agestr double(Total Male Female) float zero
    1960  1 "Under 5"   20321000 -10.33 9.991 0
    1960  2 "5 to 9"    18691000 -9.504 9.187 0
    1960  3 "10 to 14"  16773000 -8.524 8.249 0
    1960  4 "15 to 19"  13220000 -6.634 6.586 0
    1960  5 "20 to 24"  10800000 -5.272 5.528 0
    1960  6 "25 to 29"  10869000 -5.333 5.536 0
    1960  7 "30 to 34"  11949000 -5.846 6.103 0
    1960  8 "35 to 39"  12482000  -6.08 6.402 0
    1960  9 "40 to 44"  11600000 -5.676 5.924 0
    1960 10 "45 to 49"  10880000 -5.358 5.522 0
    1960 11 "50 to 54"   9606000 -4.735 4.871 0
    1960 12 "55 to 59"   8430000 -4.127 4.303 0
    1960 13 "60 to 64"   7142000 -3.409 3.733 0
    1960 14 "65 to 69"   6258000 -2.931 3.327 0
    1960 15 "70 to 74"   4739000 -2.185 2.554 0
    1960 16 "75 and up"  5563000 -2.387 3.176 0
    end
    Here are two codes I tried. Both incur an "invalid 'bar'" error.

    Code:
    twoway bar Male agegrp if YEAR==1960,  horizontal xvarlab(Males) bar(1, color(ltkhaki))||bar  Female agegrp if YEAR==1960 , horizontal xvarlab(Females) bar(1, color(ltkhaki)) , xtitle("Population(millions)") ytitle("Age")plotregion(style(none))ysca(noline) ylabel(1 "0" 6 "25" 10 "45" 14 "65")xsca(noline titlegap(-3.5))xlabel(-12 "12" -10 "10" -8 "8" -6 "6" -4 "4" 4(2)12 , tlength(0) grid gmin gmax)legend(label(1 Males) label(2 Females)) legend(order(1 2))title("1960") name(panelb, replace) nodraw
    Code:
    twoway bar Male agegrp if YEAR==1960,  horizontal xvarlab(Males) ||bar  Female agegrp if YEAR==1960 , horizontal xvarlab(Females), bar(1, color(ltkhaki)) xtitle("Population(millions)") ytitle("Age")plotregion(style(none))ysca(noline) ylabel(1 "0" 6 "25" 10 "45" 14 "65")xsca(noline titlegap(-3.5))xlabel(-12 "12" -10 "10" -8 "8" -6 "6" -4 "4" 4(2)12 , tlength(0) grid gmin gmax)legend(label(1 Males) label(2 Females)) legend(order(1 2))title("1960") name(panelb, replace) nodraw
    Any help would be greatly appreciated!

    Amie

    *Edited to remove the play(pyramid) recording and changed color from red to ltkhaki since the default will be blue and red.
    Last edited by Amie Osborn; 31 Mar 2016, 11:54.

  • #2
    You're mixing graph bar and twoway bar syntax here. One of the oddities about graph is that these commands are quite disjoint.

    This shows the main idea, repeating the twoway bar call for distinct groups.

    Code:
    twoway ///
    bar Male agegrp if YEAR==1960 & agegrp == 1, bcolor(blue) horizontal || ///
    bar Male agegrp if YEAR==1960 & agegrp != 1, bcolor(ltblue) horizontal xvarlab(Males) || ///
    bar  Female agegrp if YEAR==1960 , horizontal xvarlab(Females) ///
    xtitle("Population(millions)") ytitle("Age") ///
    plotregion(style(none))ysca(noline) ylabel(1 "0" 6 "25" 10 "45" 14 "65") ///
    xsca(noline titlegap(-3.5)) xlabel(-12 "12" -10 "10" -8 "8" -6 "6" -4 "4" 4(2)12 , tlength(0) grid gmin gmax) ///
    legend(label(1 Males) label(2 Females) order(1 2)) title("1960")

    Comment


    • #3
      Nick,

      Thank you for correcting me on my mix up of graph bar and twoway bar.

      I was able to get the code to work for my needs; however, one year seems to be having a bit more difficulty than the others. In 2010, I want to show two generations (baby boomers & millennials). Everything is as expected, except there are vertical lines WITHIN bars 9 & 13-18. They are not only other similar bars (#1 & 2) and do not show up in other years.

      The 2010 data is:
      Code:
      * Example generated by -dataex-. To install: ssc install dataex
      clear
      input int YEAR byte agegrp double(Male Female) float zero
      2010  1          -10.319427  9.881935 0
      2010  2          -10.389638  9.959019 0
      2010  3          -10.579862 10.097332 0
      2010  4          -11.303666 10.736677 0
      2010  5          -11.014176 10.571823 0
      2010  6          -10.635591 10.466258 0
      2010  7             -9.9965  9.965599 0
      2010  8          -10.042022  10.13762 0
      2010  9          -10.393977 10.496987 0
      2010 10          -11.209085 11.499506 0
      2010 11          -10.933274 11.364851 0
      2010 12           -9.523648 10.141157 0
      2010 13             -8.0775  8.740424 0
      2010 14  -6.057911399999999  6.970146 0
      2010 15          -4.0386076  4.646764 0
      2010 16 -3.2860571999999997  4.550616 0
      2010 17 -2.1907048000000002  3.033744 0
      2010 18           -1.789679  3.703754 0
      end

      while the code I am using is:
      Code:
      twoway ///
      bar Male agegrp if YEAR==2010 & agegrp <14 & agegrp>9, bcolor(erose) horizontal || ///
      bar Male agegrp if YEAR==2010 & agegrp <9 & agegrp>2, bcolor(erose) horizontal || ///
      bar Male agegrp if YEAR==2010 & agegrp <3 | agegrp==9 | agegrp>13, bcolor(edkblue) horizontal xvarlab(Males) || ///
      bar  Female agegrp if YEAR==2010 & agegrp <14 & agegrp>9, bcolor(erose) horizontal || ///
      bar  Female agegrp if YEAR==2010 & agegrp <9 & agegrp>2, bcolor(erose) horizontal || ///
      bar  Female agegrp if YEAR==2010 & agegrp <3 | agegrp==9 | agegrp>13, bcolor(edkblue) horizontal xvarlab(Females) ///
      xtitle("") ytitle("Age") ///
      plotregion(style(none))ysca(noline) ylabel(1 "0" 6 "25" 10 "45" 14 "65" 18 "85") ///
      xsca(noline titlegap(-3.5)) xlabel(-12 "12" -10 "10" -8 "8" -6 "6" -4 "4" 4(2)12 , tlength(0) grid gmin gmax) ///
      legend(off) title("2010")
      Any ideas?

      Thank you again!

      Amie

      Comment


      • #4
        Please ignore last question in the previous reply. If you are looking for the code to make this work, generate dummy variables for each generation:

        Code:
        generate boomers=1 if YEAR==1960 & agegrp<4 | YEAR==2010 & agegrp>9 & agegrp<14|YEAR==2060 & agegrp==18
        generate millennials=1 if YEAR==2010 & agegrp<8 & agegrp>2|YEAR==2060 & agegrp<18 & agegrp>12
        generate other=1 if boomers==. & millennials==.
        Then you can create your code with these categorical variables (it is much simpler):

        Code:
        twoway ///
        bar Male agegrp if YEAR==2010 & boomers==1, bcolor("255 192 0") horizontal || ///
        bar Male agegrp if YEAR==2010 & millennials==1, bcolor("192 0 0") horizontal || ///
        bar Male agegrp if YEAR==2010 & other==1 , bcolor("91 155 213") horizontal xvarlab(Males) || ///
        bar  Female agegrp if YEAR==2010 & boomers==1, bcolor("255 192 0") horizontal || ///
        bar  Female agegrp if YEAR==2010 & millennials==1, bcolor("192 0 0") horizontal || ///
        bar  Female agegrp if YEAR==2010 & other==1, bcolor("91 155 213") horizontal xvarlab(Females) ///
        xtitle("") ytitle("Age") ///
        plotregion(style(none))ysca(noline) ylabel(1 "0" 6 "25" 10 "45" 14 "65" 18 "85") ///
        xsca(noline titlegap(-3.5)) xlabel(-12 "12" -10 "10" -8 "8" -6 "6" -4 "4" 4(2)12 , tlength(0) grid gmin gmax) ///
        legend(off) title("2010")nodraw

        Comment


        • #5
          A bit of shameless - truly - self promotion, the brewscheme package could also be used to help reduce some of this code by creating a scheme with the barc parameter set to 4 or more; this will recycle the same four colors from the palette chosen for bar graphs for the maximum number of colors used in the scheme. Then you could eliminate some of the boilerplate/aesthetic code. In addition to saving time if you need to do something like this in the future, it also makes it a bit easier to maintain the existing code since the aesthetic parameters are able to persist independently of the graph commands.

          Comment


          • #6
            Thanks for the example, which runs straight away (if only everyone would do this).

            Incidentally, you don't spell it out but I take it these are for the United States and the units are millions.

            But I see no problem with the graph.

            On a different note, I have to say that I think these pyramids are vastly overrated. They presuppose that you can compare the lengths of two bars that are not in the same space. I can't do that easily. I much prefer this kind of display. I know that there's a lack of logic to showing lines for a series of binned frequencies but I can grasp the main patterns much more easily from this graph. It is true that bars of similar height can't be superimposed easily, which I suppose is a major reason for the pyramid design, but that's not the only alternative.

            Click image for larger version

Name:	notapyramid.png
Views:	1
Size:	31.9 KB
ID:	1333541


            This has been my prejudice for several years, but I can recollect only one book saying so too:

            Cliff, A.D. and Haggett, P. 1988. Atlas of disease distributions: analytic approaches to epidemiological data. Oxford: Blackwell.

            Code:
            clear
            input int YEAR byte agegrp double(Male Female) float zero
            2010  1          -10.319427  9.881935 0
            2010  2          -10.389638  9.959019 0
            2010  3          -10.579862 10.097332 0
            2010  4          -11.303666 10.736677 0
            2010  5          -11.014176 10.571823 0
            2010  6          -10.635591 10.466258 0
            2010  7             -9.9965  9.965599 0
            2010  8          -10.042022  10.13762 0
            2010  9          -10.393977 10.496987 0
            2010 10          -11.209085 11.499506 0
            2010 11          -10.933274 11.364851 0
            2010 12           -9.523648 10.141157 0
            2010 13             -8.0775  8.740424 0
            2010 14  -6.057911399999999  6.970146 0
            2010 15          -4.0386076  4.646764 0
            2010 16 -3.2860571999999997  4.550616 0
            2010 17 -2.1907048000000002  3.033744 0
            2010 18           -1.789679  3.703754 0
            end
            replace Male = -Male 
            replace agegrp = 5 * agegrp 
            set scheme s1color 
            twoway line Male Female agegrp, lcolor(blue pink) lp(dash solid) /// 
            xla(0(10)90) xtic(5(10)85) ytitle(Population (m)) yla(, ang(h)) /// 
            legend(pos(1) ring(0) col(1)) xtitle(Age (years))
            In addition, if people are interested in a sex ratio, then they should plot it directly.

            Comment


            • #7
              wbuchanan : Thank you for the information. If I need to make another similar graphic, I will be sure to look at the Stata package link you provide above. Hopefully it will help someone in a similar situation.

              Nick Cox : You are correct. As this is my final piece to my research poster, I left off the title, source, units etc. and have included these in a combined graph.

              I would tend to agree with you that a single population pyramid is probably not the best choice for identifying the true concentration of the population. For question and clarification purposes, I only provided one year of data; however, my research focuses on the impacts of demographic shifts in the U.S. Below is a code of the comparison between historical and predicted population pyramids which provide a great example of the transition seen in recent decades and the expectation of future impacts. I add a code to play a recorded editor for final touchups, but this code still gives the general concept of my comparison. Hope it helps someone!


              Thanks again for the help!!
              Amie


              Code:
              * Example generated by -dataex-. To install: ssc install dataex
              clear
              input int YEAR byte agegrp str9 agestr double(Total Male Female) float(zero boomers millennials other)
              1944  1 "Under 5"            12644540           -6.438293  6.206247 0 . . 1
              1944  2 "5 to 9"             11168095           -5.682759  5.485336 0 . . 1
              1944  3 "10 to 14"           10748443           -5.447873   5.30057 0 . . 1
              1944  4 "15 to 19"           11305978           -5.446659  5.859319 0 . . 1
              1944  5 "20 to 24"            9982174           -3.873215  6.108959 0 . . 1
              1944  6 "25 to 29"            9710781           -3.895733  5.815048 0 . . 1
              1944  7 "30 to 34"           10282240            -4.74028   5.54196 0 . . 1
              1944  8 "35 to 39"            9696497           -4.640735  5.055762 0 . . 1
              1944  9 "40 to 44"            9163708           -4.497546  4.666162 0 . . 1
              1944 10 "45 to 49"            8418320             -4.1982   4.22012 0 . . 1
              1944 11 "50 to 54"            7784007           -3.938154  3.845853 0 . . 1
              1944 12 "55 to 59"            6617369           -3.378113  3.239256 0 . . 1
              1944 13 "60 to 64"            5165890           -2.609618  2.556272 0 . . 1
              1944 14 "65 to 69"            4002453           -1.975605  2.026848 0 . . 1
              1944 15 "70 to 74"            2895674            -1.39836  1.497314 0 . . 1
              1944 16 "75 and up"           2977102           -1.379601  1.597501 0 . . 1
              2060  1 "Under 5"            22778379          -11.651752 11.126627 0 . . 1
              2060  2 "5 to 9"             22893686          -11.701628 11.192058 0 . . 1
              2060  3 "10 to 14"           22870518          -11.685481 11.185037 0 . . 1
              2060  4 "15 to 19"           23066671          -11.789972 11.276699 0 . . 1
              2060  5 "20 to 24"           23999332          -12.288607 11.710725 0 . . 1
              2060  6 "25 to 29"           25064814          -12.824985 12.239829 0 . . 1
              2060  7 "30 to 34"           25845067          -13.209786 12.635281 0 . . 1
              2060  8 "35 to 39"           26151118          -13.360831 12.790287 0 . . 1
              2060  9 "40 to 44"           25948680          -13.240612 12.708068 0 . . 1
              2060 10 "45 to 49"           25368021          -12.920705 12.447316 0 . . 1
              2060 11 "50 to 54"           25394932          -12.885485 12.509447 0 . . 1
              2060 12 "55 to 59"           24892603          -12.559795 12.332808 0 . . 1
              2060 13 "60 to 64"           24357042           -12.20071 12.156332 0 . 1 .
              2060 14 "65 to 69"           24111639          -11.967085 12.144554 0 . 1 .
              2060 15 "70 to 74"           21661957          -10.522546 11.139411 0 . 1 .
              2060 16 "75 to 79"           18392632           -8.655006  9.737626 0 . 1 .
              2060 17 "80 to 84"           14273615           -6.453631  7.819984 0 . 1 .
              2060 18 "85 and up"          19723904           -7.845194  11.87871 0 1 . .
              2010  1 "Under 5"            20201362          -10.319427  9.881935 0 . . 1
              2010  2 "5 to 9"             20348657          -10.389638  9.959019 0 . . 1
              2010  3 "10 to 14"           20677194          -10.579862 10.097332 0 . 1 .
              2010  4 "15 to 19"           22040343          -11.303666 10.736677 0 . 1 .
              2010  5 "20 to 24"           21585999          -11.014176 10.571823 0 . 1 .
              2010  6 "25 to 29"           21101849          -10.635591 10.466258 0 . 1 .
              2010  7 "30 to 34"           19962099             -9.9965  9.965599 0 . 1 .
              2010  8 "35 to 39"           20179642          -10.042022  10.13762 0 . . 1
              2010  9 "40 to 44"           20890964          -10.393977 10.496987 0 . . 1
              2010 10 "45 to 49"           22708591          -11.209085 11.499506 0 1 . .
              2010 11 "50 to 54"           22298125          -10.933274 11.364851 0 1 . .
              2010 12 "55 to 59"           19664805           -9.523648 10.141157 0 1 . .
              2010 13 "60 to 64"           16817924             -8.0775  8.740424 0 1 . .
              2010 14 "65 to 69"         13028057.4  -6.057911399999999  6.970146 0 . . 1
              2010 15 "70 to 74"          8685371.6          -4.0386076  4.646764 0 . . 1
              2010 16 "75 to 79"  7836673.199999999 -3.2860571999999997  4.550616 0 . . 1
              2010 17 "80 to 84"  5224448.800000001 -2.1907048000000002  3.033744 0 . . 1
              2010 18 "85 and up"           5493433           -1.789679  3.703754 0 . . 1
              1960  1 "Under 5"            20321000              -10.33     9.991 0 1 . .
              1960  2 "5 to 9"             18691000              -9.504     9.187 0 1 . .
              1960  3 "10 to 14"           16773000              -8.524     8.249 0 1 . .
              1960  4 "15 to 19"           13220000              -6.634     6.586 0 . . 1
              1960  5 "20 to 24"           10800000              -5.272     5.528 0 . . 1
              1960  6 "25 to 29"           10869000              -5.333     5.536 0 . . 1
              1960  7 "30 to 34"           11949000              -5.846     6.103 0 . . 1
              1960  8 "35 to 39"           12482000               -6.08     6.402 0 . . 1
              1960  9 "40 to 44"           11600000              -5.676     5.924 0 . . 1
              1960 10 "45 to 49"           10880000              -5.358     5.522 0 . . 1
              1960 11 "50 to 54"            9606000              -4.735     4.871 0 . . 1
              1960 12 "55 to 59"            8430000              -4.127     4.303 0 . . 1
              1960 13 "60 to 64"            7142000              -3.409     3.733 0 . . 1
              1960 14 "65 to 69"            6258000              -2.931     3.327 0 . . 1
              1960 15 "70 to 74"            4739000              -2.185     2.554 0 . . 1
              1960 16 "75 and up"           5563000              -2.387     3.176 0 . . 1
              end
              twoway ///
              bar Male agegrp if YEAR==1944 , bcolor("91 155 213") horizontal xvarlab(Males) || ///
              bar  Female agegrp if YEAR==1944 , bcolor("91 155 213") horizontal xvarlab(Females) ///
              xtitle("") ytitle("Age") ///
              plotregion(style(none))ysca(noline) ylabel(1 "0" 6 "25" 10 "45" 14 "65") ///
              xsca(noline titlegap(-3.5)) xlabel(-12 "12" -10 "10" -8 "8" -6 "6" -4 "4" 4(2)12 , tlength(0) grid gmin gmax) ///
              legend(off) title("1944")nodraw
              
              
              twoway ///
              bar Male agegrp if YEAR==1960 & boomers==1, bcolor("255 192 0") horizontal || ///
              bar Male agegrp if YEAR==1960 & boomers!=1, bcolor("91 155 213") horizontal xvarlab(Males) || ///
              bar  Female agegrp if YEAR==1960 & boomers==1, bcolor("255 192 0") horizontal || ///
              bar  Female agegrp if YEAR==1960& boomers!=1, bcolor("91 155 213") horizontal xvarlab(Females) ///
              xtitle("") ytitle("Age") ///
              plotregion(style(none))ysca(noline) ylabel(1 "0" 6 "25" 10 "45" 14 "65") ///
              xsca(noline titlegap(-3.5)) xlabel(-12 "12" -10 "10" -8 "8" -6 "6" -4 "4" 4(2)12 , tlength(0) grid gmin gmax) ///
              legend(off) title("1960")nodraw
              
              
              
              twoway ///
              bar Male agegrp if YEAR==2010 & boomers==1, bcolor("255 192 0") horizontal || ///
              bar Male agegrp if YEAR==2010 & millennials==1, bcolor("192 0 0") horizontal || ///
              bar Male agegrp if YEAR==2010 & other==1 , bcolor("91 155 213") horizontal xvarlab(Males) || ///
              bar  Female agegrp if YEAR==2010 & boomers==1, bcolor("255 192 0") horizontal || ///
              bar  Female agegrp if YEAR==2010 & millennials==1, bcolor("192 0 0") horizontal || ///
              bar  Female agegrp if YEAR==2010 & other==1, bcolor("91 155 213") horizontal xvarlab(Females) ///
              xtitle("") ytitle("Age") ///
              plotregion(style(none))ysca(noline) ylabel(1 "0" 6 "25" 10 "45" 14 "65" 18 "85") ///
              xsca(noline titlegap(-3.5)) xlabel(-12 "12" -10 "10" -8 "8" -6 "6" -4 "4" 4(2)12 , tlength(0) grid gmin gmax) ///
              legend(off) title("2010")nodraw
              
              
              
              
              twoway ///
              bar Male agegrp if YEAR==2060& boomers==1, bcolor("255 192 0") horizontal || ///
              bar Male agegrp if YEAR==2060 & millennials==1, bcolor("192 0 0") horizontal || ///
              bar Male agegrp if YEAR==2060 & other==1, bcolor("91 155 213") horizontal xvarlab(Males) || ///
              bar  Female agegrp if YEAR==2060 & boomers==1, bcolor("255 192 0") horizontal || ///
              bar  Female agegrp if YEAR==2060 & millennials==1, bcolor("192 0 0") horizontal || ///
              bar  Female agegrp if YEAR==2060 & other==1, bcolor("91 155 213") horizontal xvarlab(Females) ///
              xtitle("") ytitle("Age") ///
              plotregion(style(none))ysca(noline) ylabel(1 "0" 6 "25" 10 "45" 14 "65" 18 "85") ///
              xsca(noline titlegap(-3.5)) xlabel(-12 "12" -10 "10" -8 "8" -6 "6" -4 "4" 4(2)12 , tlength(0) grid gmin gmax) ///
              legend(off) title("2060")nodraw
              
              
              
              
              graph combine panela panelb panelc paneld, cols(2) title("U.S. Population Pyramid: Historical vs. Predicted (population in millions)") note("Source:(Historical)U.S. Census Bureau, Statistical Abstract (1944)Table 23; (1965)Table 5; (2010) Table 7" "        (Predicted 2060)U.S. Census Bureau, National Projections 2014, Table 1")

              Comment

              Working...
              X