Announcement

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

  • Graph Bar - Combining Graphs, adding a single legend for two bar graphs

    Hi everyone!

    I am trying to combine two graphs and add a single legend, as their respective legends are identical.

    I already looked at this ( https://www.stata.com/statalist/arch.../msg00931.html ) post, but couldn't find the answers to my questions.

    In the code below I would like the combined graph to show the same legend that Graph2 has. If I leave the code just as it is, Stata generates an image with two graphs and one legend, but one of the graphs is wider than the other due to
    Code:
     legend(off)
    .



    Code:
    Graph bar CashtoAt, over(taxuncty) asy bar(1, color(gs4)) bar(2, color(gs12)) graphregion(color(white)) title("Mean Cash-to-Assets", size(medium) position(6)) yti("") ylabel(,angle(0)) ylabel(,format(%5.4fc)) ylabel(0.0000(0.0500)0.2200) legend(off)
    
    graph save Graph1.gph, replace
    
    graph bar (median) CashtoAt, over(taxuncty) asy bar(1, color(gs4)) bar(2, color(gs12)) graphregion(color(white)) title("Median Cash-to-Assets", size(medium) position(6)) yti("") ylabel(,angle(0)) ylabel(,format(%5.4fc)) ylabel(0.0000(0.0500)0.2200)  legend(order(2 1))legend(rows(2)) legend(region(lwidth(none))) legend(bm(left)) legend(symxsize(*1)) legend(position(3))
    
    graph save Graph2.gph, replace 
    
    graph combine Graph1.gph Graph2.gph
    graph export Figure1a.png, replace

    Any help is very appreciated!

  • #2
    The post you quoted suggests using a different command grc1leg from ssc. You can install this using
    Code:
    ssc install grc1leg
    . Did you try this? grc1leg was developed for this purpose and will make your life easier.
    Last edited by Felix Stips; 26 Feb 2021, 08:43.

    Comment


    • #3
      As I understand it -- no data shown, no graph shown, you have two bar chart graphs that you want to show side by side.

      Why so? Means and medians can be shown in one graph, making direct comparison easy and avoiding this problem altogether.


      Code:
      sysuse auto, clear
      egen median = median(mpg) , by(rep78)
      egen mean = mean(mpg), by(rep78)
      scatter mean median rep78, ms(Oh +) yla(, ang(h)) xla(1/5, grid) legend(pos(12)) ytitle("`: var label mpg'")
      Click image for larger version

Name:	mean_median.png
Views:	1
Size:	22.0 KB
ID:	1595239

      Comment


      • #4
        Thank you Nick, thank you Felix.


        I followed your advice Felix and installed the package.
        Through your advice I was able to get closer to what I was looking for.


        My (slightly altered) code is:

        Code:
        Graph bar CashtoAt, over(taxuncty) asy bar(1, color(gs4)) bar(2, color(gs12)) graphregion(color(white)) title("Mean Cash-to-Assets", size(medium) position(6)) yti("") ylabel(,angle(0)) ylabel(,format(%5.4fc)) ylabel(0.0000(0.0500)0.2200) legend(order(2 1))legend(rows(2)) legend(bm(left)) legend(symxsize(*0.5)) legend(position(3)) legend(size(small))
        
        graph save Graph1.gph, replace
        
        graph bar (median) CashtoAt, over(taxuncty) asy bar(1, color(gs4)) bar(2, color(gs12)) graphregion(color(white)) title("Median Cash-to-Assets", size(medium) position(6)) yti("") yscale(lstyle(none)) ylabel(,format(%5.4fc)) ylabel(none) legend(order(2 1))legend(rows(2)) legend(bm(left)) legend(symxsize(*0.5)) legend(position(3)) legend(size(small)) 
        graph save Graph2.gph, replace 
        
        grc1leg Graph1.gph Graph2.gph, position(3)
        graph export Figure1a.png, replace
        After executing the Do-file I get this graph:


        Click image for larger version

Name:	Figure1a.png
Views:	1
Size:	19.7 KB
ID:	1595266


        And here is what I am trying to replicate:

        Click image for larger version

Name:	Screenshot (34).png
Views:	1
Size:	30.9 KB
ID:	1595267



        As you can see I am really close, but a few things still need fixing.

        If possible I would like to keep the scale of the two graphs and width of the bars consistent.

        I already tried adding - xcommon - to have them displayed on a single x-axis, but this seems to have no effect.
        Changing the margin colour through - plotregion(margin(color(white))) - , in either the final or the other two graphs was also unsuccessful.

        My main issue, however, is keeping the scale consistent and keeping the vertical lines to indicate spacing.


        Many thanks in advance to whoever answers!

        Comment


        • #5
          Hi everyone,
          I have exactly the same problem as Stefanie when I use the graph combine command with bar charts: the width of the bars is not equal and I cannot get a single x-axis for both graphs.

          Does anyone know how to solve these problems?

          Thanks a lot!

          Comment


          • #6
            Hello Daniel Labarca. How many groups do you have? I'm wondering if the approach Nick Cox used in #2 here might be better than clustered bar charts.
            --
            Bruce Weaver
            Email: [email protected]
            Version: Stata/MP 18.5 (Windows)

            Comment


            • #7
              Originally posted by Bruce Weaver View Post
              Hello Daniel Labarca. How many groups do you have? I'm wondering if the approach Nick Cox used in #2 here might be better than clustered bar charts.
              Bruce Weaver I was looking for a similar graph over the last days. The only difference is how is it possible to add a second y to the right by groups in #4?

              Comment


              • #8
                We have now two people in 24 hours claiming the same or similar problem (#5 and #7) but with no specific details Would either or both of you spell out a reproducible data example please?

                If the problem is bar charts of means and medians, then use collapse to give us a data example to work with.

                If the problem is not quite that, our need for a data example is even greater.

                Note that graph bar can't be combined with two y axes, which is usually a bad idea any way.

                If means and medians are very different, perhaps you need logarithmic scale and/or geometric mean instead.

                Comment


                • #9
                  My problem is exactly the same one Stefanie showed in #4. If one wants to combine two graphs sharing the same y-axis one gets different sizes of the bars. The graph that was created without a y-axis (auto2) shows wider bars compared to the graph that was created with a y-axis (auto1). On the other hand, I also couldn’t find a way to have both graphs be on the same x-axis.

                  Here a small example:

                  Code:
                  sysuse auto,clear
                  
                  replace rep78=. if rep78==1 | rep78==2
                  
                  set scheme  s2color  
                  
                   graph bar (percent) if foreign==0, over(rep78, gap(*0.1) label(labsize(medsmall ))) blabel(bar, position(outside) size(medsmall ) format(%9.2fc)) ytitle("") title("")  ylabel(10 (10)80, nogrid labsize(medsmall ))  bargap(1) bar(1, color(navy %85)) graphregion(color(white)) bgcolor(white) plotregion(style(none)) name(auto1, replace)
                   
                  graph export "$figures\auto1.png", replace
                  
                   graph bar (percent) if foreign==1, over(rep78, gap(*0.1) label(labsize(medsmall ))) blabel(bar, position(outside) size(medsmall ) format(%9.2fc)) ytitle("") title("")  ylabel(10 (10)80, nogrid nolabel noticks) yscale(lstyle(none)) bargap(1) bar(1, color(cranberry   %90)) graphregion(color(white)) bgcolor(white) plotregion( style(none)) name(auto2, replace)    
                   
                  graph export "$figures\auto2.png", replace
                   
                   graph combine  auto1 auto2, imargin(0 0) commonscheme row(1)  title("{bf:Probability Harming/Praising} (weighted data)", size(medsmall)) l1title("Frequency in %", size(small))  graphregion(color(white))  plotregion( style(none))
                  Click image for larger version

Name:	Screenshot (25).png
Views:	1
Size:	44.3 KB
ID:	1695783


                  As you can see the cranberry-colored bars are wider than the blue ones and they do not share a common x-axis, there is a gap between both graphs.

                  Last edited by Daniel Labarca; 03 Jan 2023, 09:45.

                  Comment


                  • #10
                    The main trick here is to use a by() option, and not to use graph combine at all, as you have to wrestle with the fact that y axis stuff is shown in one panel but not the other. For the moral see https://journals.sagepub.com/doi/epu...36867X20976341 and for one code solution among several consider


                    Code:
                    sysuse auto,clear
                    
                    replace rep78=. if rep78==1 | rep78==2
                    
                    set scheme  s1color  
                    
                    drop if missing(rep78)
                    
                    contract foreign rep78
                    egen _total = total(_freq), by(foreign)
                    gen _pc = 100 * _freq / _total
                    separate _pc, by(foreign)
                    
                    graph bar (asis) _pc?, over(rep78) by(foreign, title("{bf:Probability Harming/Praising} (weighted data)")  l1title("Frequency in %", size(small)) legend(off) note("")) nofill blabel(bar, format(%9.2fc)) subtitle("")  bar(1, color(navy%85)) bar(2, color(cranberry%90))
                    Click image for larger version

Name:	dontusecombine.png
Views:	1
Size:	21.8 KB
ID:	1695791

                    Last edited by Nick Cox; 03 Jan 2023, 10:34.

                    Comment


                    • #11
                      Here's another approach. The main point is that there are several ways to do this that don't imply graph combine. tabplot is from the Stata Journal.


                      Code:
                      sysuse auto,clear
                      
                      replace rep78=. if rep78==1 | rep78==2
                      
                      set scheme  s1color  
                      
                      tabplot rep78, by(foreign, imargin(zero)) percent(foreign) showval(mlabsize(medium) offset(0.05)) separate(foreign) bar1(color(cranberry)) bar2(color(navy)) ytitle(Percent)
                      Click image for larger version

Name:	notcombine.png
Views:	1
Size:	15.4 KB
ID:	1695918

                      Comment


                      • #12
                        Originally posted by Nick Cox View Post
                        We have now two people in 24 hours claiming the same or similar problem (#5 and #7) but with no specific details Would either or both of you spell out a reproducible data example please?

                        If the problem is bar charts of means and medians, then use collapse to give us a data example to work with.

                        If the problem is not quite that, our need for a data example is even greater.

                        Note that graph bar can't be combined with two y axes, which is usually a bad idea any way.

                        If means and medians are very different, perhaps you need logarithmic scale and/or geometric mean instead.


                        Nick Cox I have created a new thread for my case.
                        https://www.statalist.org/forums/for...-y#post1696420


                        I would much appreciate if you could take a minute or two to review my question. Thanks

                        Comment

                        Working...
                        X