Announcement

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

  • Stacked bar - single chart for multiple variables

    Hello everybody,

    I am trying to reproduce the attached chart, meaning stacked bars of multiple categorical variables (socio-demographics) by a common categorical variable (cluster). It's easy to do each series with the following code:

    Code:
    graph hbar (count), over(cluster) over(male) percent stack asyvars
    But is it possible to add bars for multiple variables? I tried "graph common" as well as "grc1leg" using the "col(1)" option, but graph region sizes are different, as is label width, etc. Basically I would like to add stacked bars to the same graph region and separate them with a gap (like the attached image). Is it possible?

    Thanks!!!
    Attached Files

  • #2
    Update: I've looked at the "designplot" command, which seems to allow for additional variables. However unless I'm mistaken, it doesn't seem to allow to interact multiple variables by a single one (in my case something like "over(cluster)". Any ideas?

    Thanks!

    Comment


    • #3
      I would bet that you'll get more responses if you provide a data example and the code for the error /issue you reported ("I tried "graph common" as well as "grc1leg" using the "col(1)" option" ) so that others can help you fix your code. I generally try to avoid stacked bars and I would guess there exists some better way to do this, but here's a hackish approach which produces the attached figure:

      Code:
      **combine stacked bar chart example**
       set scheme s1color
       clear
       set obs 100
       g engagement = int(runiform()*4)
       g age = int(runiform()*4)
       g gender = rbinomial(1, .45)
       g cars = int(runiform()*2)
       lab def engagement 0 "Dismissive" 1 "Skeptic" 2 "Aware" 3 "Empowered", modify
       lab val engagement engagement
       lab def gender 0 "Male" 1 "Female", modify
       lab def cars  0 "zero" 1 "lots"
       lab val cars cars
       lab val gender gender
       
        catplot engagement,  over(cars)  stack percent(cars) asyvars yla(0(25)100) 
        statplot cars , over(engagement)  stack percent asyvars
      
        loc i = 1
       foreach j in cars age gender  {
      **options for graph
          if `i' == 3 loc legg `"legend(on pos(6) row(1) region(lcolor(none)))"'
          if `i' !=3 loc axis `"ylabel(none, nolabels nogrid) "'
          if `i' == 3 loc axis `"yla(0(25)100, nogrid) "'
              lab var engagement `"`=upper("`j'")'"'
              **manually adjust left margin/label distance::
              loc diff = 0
              if `"`j'"' == "cars" loc diff = 5.33
                if `"`j'"' == "age" loc diff = 9.33
      **graph    
      catplot engagement , over(`j')   stack percent(`j') asyvars ///
            legend(off) `legg' blabel(bar, format(%3.1f) size(small) pos(inside) color(gs12)) ///
            name(g`i', replace)   `axis'      plotregion(fcolor(none) lcolor(none)) l1title("`=upper("`j'")'", margin(0 `diff' 0 0 )) ytitle("") yscale(noline)  yline(25 50 75, extend)
              loc plots `"`plots' g`i' "'
              loc `++i'
            }
            
            gr combine `plots', colfirst ycommon cols(1) imargin(zero) graphregion(margin(large))

      Click image for larger version

Name:	test.png
Views:	1
Size:	164.0 KB
ID:	1403760


      Also, these articles might be helpful:
      http://www.stata-journal.com/article...article=gr0034
      http://www.stata-journal.com/sjpdf.h...iclenum=gr0004

      Eric A. Booth | Senior Director of Research | Far Harbor | Austin TX

      Comment


      • #4
        I forgot to mention that -catplot- and -statplot- were used in the previous post and they are from SSC (e.g., -ssc install catplot-)
        Eric A. Booth | Senior Director of Research | Far Harbor | Austin TX

        Comment


        • #5
          Hello eric_a_booth , thank you for sharing this information. I would like some help please to reproduce a similar chart with categorical data; location("region"), educational level ("netude") and working structure ("structrav"). All the three variables were in string format and with the command "encode" and "generate" I transformed them into numerical. Thus, "region" has 13 categories (1,2,3..13); "netude" has 6 (1,2,...6); and "structurav" has 5 (1,2,..5). My goal is to represent "region" and "netude" over "structurav", so I would like to know the procedure to do it, since I followed your example applied to my case but unfortunately I did not get the wished chart. I appreciate your time and help! thank you

          Comment


          • #6
            #5 is in essence that you have

            three categorical variables, which you don't show us

            code you don't show us either

            and you are getting a graph that you don't want.

            I can't see that eric_a_booth or anyone else has enough information there to advise you.

            More details please. Which variable do you want to stack? Do you want to show that for the cross-combinations of the other two? That is at worst 78 and at best 30 joint categories. Or as in #4 do you want separate graphs for the other two?

            Comment


            • #7
              Hello Nick Cox,

              here further details :
              My variables and code (based on #3)
              Code:
              clear
              regions structrav netude
              4 4 4
              8 3 1
              8 3 1
              8 3 1
              2 3 1
              2 1 4
              8 3 1
              9 4 5
              1 2 1
              9 2 1
              2 3 1
              9 3 1
              9 3 3
              10 4 1
              9 2 6
              
              8 1 4
              2 3 3
              8 3 3
              5 4 4
              8 3 1
              9 4 4
              5 4 5
              4 4 4
              9 4 4
              8 4 4
              9 4 1
              9 4 1
              5 4 4
              5 3 1
              5 3 5
              5 3 4
              6 3 5
              5 3 3
              8 3 1
              5 3 2
              5 3 1
              5 4 4
              8 3 1
              8 2 1
              9 3 1
              8 3 1
              8 3 1
              8 3 3
              8 3 1
              1 3 1
              8 3
              8 2 1
              8 2 1
              8 3 1
              8 3 1
              8 2 1
              8 2 1
              8 3 6
              8 2 1
              1 3 3
              5 4 5
              7 1 6
              7 4 1
              9 4 6
              8 3 1
              9 3 1
              9 1 3
              9 3 2
              9 3 2
              9 3 1
              9 3 3
              9 3 1
              9 3 3
              9 3 3
              9 3 6
              1 4 1
              9 3 3
              9 3 1
              9 3 1
              9 3 1
              9 3 1
              9 3 1
              9 3 6
              9 3 3
              9 3 1
              9 3 1
              8 3 3
              9 3 1
              9 3 1
              9 3 1
              9 3 3
              9 2 1
              9 3 1
              9 3 4
              9 3 1
              9 3 4
              9 3 1
              5 4 4
              9 3 1
              9 3 2
              9 3 1
              9 3 1
              9 3 2
              9 3 2
              7 4 4
              9 3 2
              9 3 1
              9 2 3
              7 4 4
              11 2 3
              8 2 6
              9 3 1
              11 2 4
              11 3 4
              11 3 5
              9 2 1
              9 3 5
              11 2 1
              11 3 3
              4 4 1
              8 2 1
              11 2 3
              9 2 1
              9 2 2
              9 2 1
              5 4 4
              11 2 4
              9 2 1
              10 4 4
              4 4 4
              8 3 1
              11 2 2
              8 3 1
              8 3 1
              8 3 1
              2 1
              8 3 1
              8 3 1
              8 3 1
              8 3 1
              8 3 3
              7 4 4
              8 3 1
              8 3 4
              8 3 1
              8 3 1
              8 3 1
              5 3 1
              3 3 3
              2 3 1
              2 3 1
              8 3 1
              end
              
              catplot structrav, over(regions) stack percent(regions) asyvars yla(0(25)100)
              statplot regions , over(structrav) stack percent asyvars
              
              loc i = 1
              foreach j in regions structrav netude {
              
              **options for graph
              
              if `i' == 2 loc legg `"legend(on pos(6) row(1) region(lcolor(none)))"'
              if `i' !=2 loc axis `"ylabel(none, nolabels nogrid) "'
              if `i' == 2 loc axis `"yla(0(25)100, nogrid) "'
              lab var structrav `"`=upper("`j'")'"'
              
              **manually adjust left margin/label distance::
              
              loc diff = 0
              if `"`j'"' == "regions" loc diff = 5.33
              if `"`j'"' == "netude" loc diff = 9.33
              
              **graph
              
              catplot structrav , over(`j') stack percent(`j') asyvars /// legend(off) `legg' blabel(bar, format(%3.1f) size(small) pos(inside) color(gs12)) /// name(g`i', replace) `axis' plotregion(fcolor(none) lcolor(none)) l1title("`=upper("`j'")'", margin(0 `diff' 0 0 )) ytitle("") yscale(noline) yline(25 50 75, extend) loc plots `"`plots' g`i' "' loc `++i' }
              
              gr combine `plots', colfirst ycommon cols(1) imargin(zero) graphregion(margin(large))
              when run this code I get a graph but is not as would like to, I would like to stack structrav and on Yaxis a block for region and a second one for netude. Plus, I get an error :

              option / not allowed
              r(198);

              .
              . gr combine `plots', colfirst ycommon cols(1) imargin(zero) graphregion(margin(large))
              incompatible types
              may not assign class to double
              r(4027);

              Thanks in advance for your help!
              Last edited by Mauro Florez; 20 Aug 2020, 05:00.

              Comment


              • #8
                Thanks for the code, but it is hard to follow and raises errors or puzzles quite different from those mentioned.

                Before posting, it's important to test that the code you post runs correctly. (And yes, sometimes I have messed up on that too, but my batting average is not too bad.)

                1. Your code misses out input in an early command.

                2. One data line is empty. One data line is incomplete.

                3. Some commands are mangled together in the latter part of your code.

                4; This line is quite wrong

                Code:
                 
                 loc `++i'
                should be

                Code:
                 
                 loc ++i
                5. Second time around the loop you are asking for

                Code:
                 
                 catplot structrav , over(structrav)
                and when I run your code it crashes on that request.

                So (1) I can't run your code without rewriting it (2) I believe you when you say that the result is not as you like, but I can't comment on that.

                For the record, this works for me (and anyone starting here should note that catplot and statplot need to be installed from SSC first).


                Code:
                clear
                input regions structrav netude
                4 4 4
                8 3 1
                8 3 1
                8 3 1
                2 3 1
                2 1 4
                8 3 1
                9 4 5
                1 2 1
                9 2 1
                2 3 1
                9 3 1
                9 3 3
                10 4 1
                9 2 6
                
                8 1 4
                2 3 3
                8 3 3
                5 4 4
                8 3 1
                9 4 4
                5 4 5
                4 4 4
                9 4 4
                8 4 4
                9 4 1
                9 4 1
                5 4 4
                5 3 1
                5 3 5
                5 3 4
                6 3 5
                5 3 3
                8 3 1
                5 3 2
                5 3 1
                5 4 4
                8 3 1
                8 2 1
                9 3 1
                8 3 1
                8 3 1
                8 3 3
                8 3 1
                1 3 1
                8 3
                8 2 1
                8 2 1
                8 3 1
                8 3 1
                8 2 1
                8 2 1
                8 3 6
                8 2 1
                1 3 3
                5 4 5
                7 1 6
                7 4 1
                9 4 6
                8 3 1
                9 3 1
                9 1 3
                9 3 2
                9 3 2
                9 3 1
                9 3 3
                9 3 1
                9 3 3
                9 3 3
                9 3 6
                1 4 1
                9 3 3
                9 3 1
                9 3 1
                9 3 1
                9 3 1
                9 3 1
                9 3 6
                9 3 3
                9 3 1
                9 3 1
                8 3 3
                9 3 1
                9 3 1
                9 3 1
                9 3 3
                9 2 1
                9 3 1
                9 3 4
                9 3 1
                9 3 4
                9 3 1
                5 4 4
                9 3 1
                9 3 2
                9 3 1
                9 3 1
                9 3 2
                9 3 2
                7 4 4
                9 3 2
                9 3 1
                9 2 3
                7 4 4
                11 2 3
                8 2 6
                9 3 1
                11 2 4
                11 3 4
                11 3 5
                9 2 1
                9 3 5
                11 2 1
                11 3 3
                4 4 1
                8 2 1
                11 2 3
                9 2 1
                9 2 2
                9 2 1
                5 4 4
                11 2 4
                9 2 1
                10 4 4
                4 4 4
                8 3 1
                11 2 2
                8 3 1
                8 3 1
                8 3 1
                2 1
                8 3 1
                8 3 1
                8 3 1
                8 3 1
                8 3 3
                7 4 4
                8 3 1
                8 3 4
                8 3 1
                8 3 1
                8 3 1
                5 3 1
                3 3 3
                2 3 1
                2 3 1
                8 3 1
                end
                
                catplot structrav, over(regions) stack percent(regions) asyvars yla(0(25)100)
                statplot regions , over(structrav) stack percent asyvars
                
                loc i = 1
                foreach j in regions netude {
                
                **options for graph
                
                if `i' == 2 loc legg `"legend(on pos(6) row(1) region(lcolor(none)))"'
                if `i' != 2 loc axis `"ylabel(none, nolabels nogrid) "'
                if `i' == 2 loc axis `"yla(0(25)100, nogrid) "'
                lab var structrav `"`=upper("`j'")'"'
                
                **manually adjust left margin/label distance::
                
                loc diff = 0
                
                **graph
                
                catplot structrav, over(`j')  stack percent(`j') asyvars /// 
                legend(off) `legg' blabel(bar, format(%3.1f) size(small) pos(inside) color(gs12)) /// 
                name(g`i', replace) `axis' plotregion(fcolor(none) lcolor(none)) ///
                l1title("`=upper("`j'")'", margin(0 `diff' 0 0 )) ytitle("") yscale(noline) yline(25 50 75, extend) 
                
                loc plots `"`plots' g`i' "' 
                loc ++i 
                }
                
                gr combine `plots', colfirst ycommon cols(1) imargin(zero) graphregion(margin(large))
                Code:
                
                

                Comment

                Working...
                X