Announcement

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

  • Question on how to make a stacked Bar Graph with the size and proportion of each variable

    Hello. I have a question about making stacked bar graphs that show both the size and the proportion of each variable.

    For the following example,
    year firm v1 v2 v3
    2000 A 10 20 30
    2001 A 30 50 10
    2000 B 50 40 20
    2001 B 60 10 50
    I was able to make bar graphs with the size of each variable and the proportion of each variable of each firm with the following commands:



    levelsof firm, local(fn)
    foreach f of local fn {
    preserve
    keep if firm == "`f'"
    graph bar v1-v3 , over(year) stack title("`f'") blabel(bar, pos(center))
    graph export size_of_variables_`f'.png, replace
    restore
    }

    levelsof firm, local(fn)
    foreach f of local fn {
    preserve
    keep if firm == "`f'"
    graph bar v1-v3 , percentage over(year) stack title("`f'") blabel(bar, pos(center))
    graph export proportion_of_variables_`f'.png, replace
    restore
    }

    This yields the following graphs:



    What I want is to combine the two features of the graphs, so that the graphs have varying heights depending on the size of the variable, and the labels show the percentage(proportion) of each variable. Ideally, I would want my graph to look something like this:




    I would greatly appreciate any help regarding this topic. Thank you.

    Last edited by Seung Yeol Paik; 01 Jun 2023, 20:01.

  • #2
    I can't see your graphs -- I guess because you did not post .png as requested (FAQ Advice #12). But I don't think you can get what you want with graph bar.

    With some work you can get something like it out of twoway.

    This code will need much more work if you have many more firms than 2. or more components than 3 or more years than said.


    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input int year str1 firm byte(v1 v2 v3)
    2000 "A" 10 20 30
    2001 "A" 30 50 10
    2000 "B" 50 40 20
    2001 "B" 60 10 50
    end
    
    gen total = v1 + v2 + v3 
    
    forval j = 1/3 { 
        gen pc`j' = strofreal(100 * v`j' / total, "%3.1f") 
    }
    
    gen total12 = v1 + v2 
    
    gen pos1 = v1/2 
    gen pos2 = v1 + v2/2 
    gen pos3 = total12 + v3/2 
    
    local opts  barw(0.8) xla(2000 2001)
    
    twoway bar v1 year, `opts' lcolor(red) fcolor(red*0.1) || scatter pos1 year, ms(none) mla(pc1) mlabc(red) mlabpos(0) /// 
    || rbar v1 total12 year, `opts' lcolor(blue) fcolor(blue*0.1) || scatter pos2 year, ms(none) mla(pc2) mlabc(blue) mlabpos(0) /// 
    || rbar total12 total year,  `opts' lcolor(black) fcolor(black*0.1) || scatter pos3 year, ms(none) mla(pc3) mlabc(black) mlabpos(0) by(firm, note(""))  ///
    legend(order(1 "v1" 3 "v2" 5 "v3"))
    Click image for larger version

Name:	firmstack.png
Views:	1
Size:	23.2 KB
ID:	1715871

    Last edited by Nick Cox; 02 Jun 2023, 01:40.

    Comment


    • #3
      Another take on this would be to use tabplot from the Stata Journal.

      Code:
      * Example generated by -dataex-. For more info, type help dataex
      clear
      input int year str1 firm byte(v1 v2 v3)
      2000 "A" 10 20 30
      2001 "A" 30 50 10
      2000 "B" 50 40 20
      2001 "B" 60 10 50
      end
      
      capture frame drop graphsandbox 
      
      frame put *, into(graphsandbox)
      
      frame graphsandbox { 
          reshape long v, i(firm year) j(which)
          egen pc = pc(v), by(firm year)
          gen toshow = strofreal(pc, "%2.1f") + "%"
          tabplot which year [iw=v] , by(firm, note("")) showval(toshow) separate(which) ytitle("")
      }
      As before. how well this extends to more firms ... more years? ... more components is hard to predict.

      Click image for larger version

Name:	firmstack2.png
Views:	1
Size:	23.2 KB
ID:	1715877


      Comment


      • #4
        Here is another take on that graph that gives the dimensions firm and v1, v2, v3 equal "visual weight":

        Code:
        * Example generated by -dataex-. For more info, type help dataex
        clear
        set scheme s1color
        
        input int year str1 firm byte(v1 v2 v3)
        2000 "A" 10 20 30
        2001 "A" 30 50 10
        2000 "B" 50 40 20
        2001 "B" 60 10 50
        end
        
        gen total = v1 + v2 + v3
        
        forval j = 1/3 {
            gen pc`j' = 100 * v`j' / total
        }
        
        drop v?
        reshape long pc , i(year firm) j(var)
        format pc %5.1f
        gen y = -4
        separate pc , by(var)
        
        twby var firm, compact left                    ///
                xoffset(0.5) legend(off) :             ///
            twoway bar pc? year,                       ///
                xlab(2000 2001) ylab(none) barw(.9 ..) ///
                ytitle("") ||                          ///
            scatter y year, mlabel(pc) mlabpos(0)      ///
                msymbol(i) mlabcolor(black)
        Click image for larger version

Name:	Graph.png
Views:	1
Size:	45.4 KB
ID:	1715882
        ---------------------------------
        Maarten L. Buis
        University of Konstanz
        Department of history and sociology
        box 40
        78457 Konstanz
        Germany
        http://www.maartenbuis.nl
        ---------------------------------

        Comment


        • #5
          @Maarten Buis' variation requires twby from SSC.

          Comment


          • #6
            Wow, thank you both so much for your great answers.

            I apologize for my inadequate post. I did post the png files, but then I deleted the attachments because I thought they were already included in the post.

            The first answer using the two-way plot is exactly what I needed, but like you said, I will have to try and find a compact way of applying it to many variables and many firms.

            Again, thank you both very much! I greatly appreciate your help!

            Comment

            Working...
            X