Announcement

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

  • Combined graphs with a single legend: Update of -grc1leg2- to version 2.11

    In 2010 Vince Wiggins (StataCorp) released his utility -grc1leg- for attaching a single legend to a multi-panel array of previously created graphs. Ever since version 8, Stata's -graph ..., by()- {help graph_by} command has provided a way to accomplish this objective. But as paulvonhippel has pointed out here , there are circumstances in which one wants to make a multi-panel graph with a single legend that are difficult or impossible to accomplish with either -graph ..., by()- or -graph combine ...-. With advice from Vince Wiggins (StataCorp) , Jeff Pitblado (StataCorp) and Derek Wagner (StataCorp), I elaborated Vince's original command to make -grc1leg2-. To add options requested by paulvonhippel, I released Version 1.60 last year which accommodates all the -graph display- options. Recently Marc Kaulisch asked whether it might be possible to alter the sizes of markers and other symbols inside the legend. Version 2.11 responds to that suggestion with additional options to allow the user to alter the sizes of all the "keys" in a legend, as well as its title and subtitle if any.

    In revisiting the program to allow changes to the marker sizes, I benefited from observations by Andrew Musau and Daniel Gross on a thread started by Florian Schneider that -grc1leg2-'s 4000 series errors thrown from Stata's -class- system {help class} might originate from the user's specifying the legend sub-option -order()- or from the user's use of the -grc1leg2- option -labsize()-. In tracking down and fixing these issues, I discovered that edits made by version 1.60 were not retained in the .gph files created by -grc1leg2-'s option --saving()-. Fixing this bug required learning a bit more about how Stata's class system works.

    Version 2.11 adds two relevant options. One is -lmsize(size)- which allows the user to adjust the size of all the markers in the legend, as Marc Kaulisch requested. It works like option -labsize(size)-, -symxsize()- and -symysize()-, but for markers. Furthermore, I found compelling Marc's point that -grc1leg2- should reduce the size of all legend elements in the combined graph BY DEFAULT. (Stata's -gr combine-'s default behavior is to downsize all text and symbols in graphs it combines.) So I have added an option -legscale(size)- which allows the user to resize all of the elements inside the legend by the same multiplicative factor. If the user does not specify -legscale()-, -grc1leg2- guesses how much to shrink all the elements according to the number of panels in the combined graph. (This default downsizing can be suppressed by the option noautosize.)

    In this revision -grc1leg2- is hopefully more polite when Stata's graphics utilities detect a class error. In some cases, -grc1leg2- detects and ignores the offending option, proceeding to create the graph with a warning message. (See Known Issue #1 in the help file.) In others, it traps the error and clears memory of scrambled memory graphs and sersets.

    The help file and the dialog have also been updated. To install or update the new version:
    Code:
    view net describe grc1leg2, from("http://digital.cgdev.org/doc/stata/MO/Misc")
    Or just type:
    Code:
    search grc1leg2
    Feel free to contact me here or by email with questions or issues. I would be particularly interested if users still encounter situations in which -grc1leg2- behaves impolitely.

  • #2
    Dear @Mead Over

    I try to run the example in the helpfile. I find a small problem.
    In example 3.13, the third scatter plot,you use the circle symbol.But in the legend, it shows the square circle.
    I think they should have the same symbol.










    Best regards.

    Raymond Zhang
    Stata 17.0,MP

    Comment


    • #3
      Here is the graph of Example 3.13.
      Attached Files
      Best regards.

      Raymond Zhang
      Stata 17.0,MP

      Comment


      • #4
        Well, here is my resulting plot (use default scheme of s2color):
        Click image for larger version

Name:	grclcolsasis.png
Views:	1
Size:	97.9 KB
ID:	1654788
        Last edited by Chen Samulsion; 16 Mar 2022, 20:38.

        Comment


        • #5
          Thanks for the quick feedback. Of course, my intention is that the markers and symbols in the legend match those in the component panel graphs. You did not sent the code you used in your attempts to reproduce Example 3.13. So I am just guessing at what might have happened in your case.

          First, looking again at the help file, note that both Example 3.10 and 3.13 use the same four component graphs (panels 7, 8, 9 and 10). Both examples have the options -legendfrom(panel10)- and -hidelegendfrom-. The only purpose of Example 3.13 is to demonstrate that -grc1leg2- can change the column layout of the legend and that the changed layout is retained in the saved .gph file. Thus I will respond to your questions with Example 3.10 and then show that the same response applies to Example 3.13.

          To my knowledge the choice of scheme should not matter. Personally I prefer the scheme -s2clr_on_white-, which one can install from the CGD web site here:

          Code:
          view net describe scheme_s2clr_on_white, from(http://digital.cgdev.org/doc/stata/MO/Misc)
          But here I use the scheme -s2color-.

          Extracted from the help file, the following code sets up the data and creates the component graphs named panels 7, 8, 9 and 10.

          Code:
          *    Set up the data
          
          graph drop _all
          set graph on
          sysuse auto2, clear
          
          drop if missing(rep78)
          
          gen byte qual = 1*(rep78<3)+2*(rep78==3)+3*(rep78>=4)
              lab def qual 1 "Low Quality"  2  "Medium Quality"  3  "High Quality"
              lab value qual qual
              lab var qual "Quality: Mapping of rep78 into trichotomy"
          
          tab rep78 qual
          
          *    Example 3.10: Making a composite legend using the -hidelegendfrom- option
          
          twoway  ///
              (scatter mpg weight, mcolor(blue)),  ///
                  name(panel7, replace)
          
          twoway  ///
              (scatter length weight, mcolor(red)),  ///
                  name(panel8, replace)
          
          twoway  ///
              (scatter price weight, mcolor(green))  ///
              (lfitci  price weight, lcolor(green)),  ///
                  ytitle(Price)  ///
                  name(panel9, replace)
          
          *    Now make the auxiliary graph, which will not be displayed.
          *    We borrow the legend from this graph:
          
          twoway  ///  This is the component graph from which we take the legend
              (scatter mpg weight, mcolor(blue))  ///        <- Match the color and shape of panel7
              (scatter length weight, mcolor(red))  ///       <- Match the color and shape of panel8
              (scatter price weight, mcolor(green))  ///     <- Match the color and shape of panel9
              (lfitci  price weight, lcolor(green)),  ///          <- Match the color and shape of panel9
                  legend(colfirst cols(2) order(1 2 3 5 4) holes(3))  ///  
                  name(panel10, replace)
          Executing the above code produces four graphs, the three graphs (panels 7, 8 and 9) intended to occupy the new combined graph and also an auxiliary fourth graph named -panel10-, which is NOT intended for display by -grc1leg2-. If we do display -panel10-, this is what we see:
          Click image for larger version

Name:	panel10.png
Views:	1
Size:	74.8 KB
ID:	1654806
          Although -panel10- is too ugly to show anyone, note that its legend contains all the proper markers, symbols and labels needed for a legend that applies to panels 7, 8 and 9. So when we execute -gtrc1leg2-, we want to borrow the legend from -panel10- (using option -legendfrom(panel10)-), but suppress the display of -panel10- (using option -hidelegendfrom-). Here's the code from the help file (using scheme -s2color to match Chen Samulsion 's post).

          Code:
          grc1leg2 panel7 panel8 panel9 panel10, scheme(s2color) ///
              title("Ex. 3.10: Assemble the legend keys from different panels"  "to construct the combined legend")  ///
              xtob1title legendfrom(panel10) hidelegendfrom  ///
              pos(4) ring(0) lyoffset(15)  ///
              name(grchide, replace)
          Click image for larger version

Name:	grchide.png
Views:	1
Size:	101.6 KB
ID:	1654807

          So I do not have the problem of mismatching markers that is seen in posts by Chen Samulsion and @Raymond Zhang.

          My guess about what happened in their two examples is that their versions of the code to create panel10 do not exactly match my code. This could happen if, instead of executing the help file code by clicking on the blue "hyperlinks", Raymond and Chen loosely approximated the code in the help file by retyping it into their own DO file.

          Assuming that's what happened, I think I can replicate the result achieved by Chen Samulsion by creating an alternative version of -panel10- called -panel10bis-.

          Code:
          twoway  ///  This is the component graph from which we take the legend
              (scatter mpg length price weight, mcolor(blue red green) msym(O D S))  ///
              (lfitci  price weight, lcolor(green)), scheme(s2color)   ///
                  legend(colfirst cols(2) order(1 2 3 5 4) holes(3))  ///  <- Avoids using the option -lcols()- of -grc1leg2-
                  name(panel10bis, replace)
          Executing this code gives a slightly different, but equally ugly, auxiliary graph called -panel10bis-.

          Click image for larger version

Name:	panel10bis.png
Views:	1
Size:	72.4 KB
ID:	1654808

          In this revised version of the auxiliary graph, the markers are changed to a diamond and a square by the option -msym(O D S)-. Now when we combine panels 7, 8 and 9 and use -panel10bis- for the legend we get:

          Click image for larger version

Name:	grchidebis.png
Views:	1
Size:	101.4 KB
ID:	1654809

          Since the borrowed legend comes from auxiliary graph -panel10bis-, it's not surprising that its markers do not match those in panels 7, 8 and 9. In the help file discussion preceding Example 3.10, I say "By specifying the colors of the markers[, symbols, labels] and fitted lines for [all] the component graphs, [including the auxiliary graph], we can assure that the markers, symbols and labels in the legend [to be borrowed from the auxiliary graph] match those in the panels to be displayed." (I now see that I should improve this sentence.)

          Using -panel10bis- instead of -panel10- to construct Example 3.13, yields the code:

          Code:
          grc1leg2 panel7 panel8 panel9 panel10bis, scheme(s2color) ///
              title("Ex. 3.13: Change the legend's row and column arrangement"  ///
              `"with lcols(1) and save to disk as an "asis" gph file"')  ///
              xtob1title legendfrom(panel10bis) hidelegendfrom  ///
              pos(4) ring(0) lxoffset(-5) lyoffset(15) lcols(1) ///
              name(grclcolsasis, replace) saving(grclcolsasis, replace asis)
          Executing -grc1leg2- with the above options seems to reproduce the graph in Chen's post like this:

          Click image for larger version

Name:	image_26226.png
Views:	1
Size:	105.2 KB
ID:	1654810

          However, if my guess about why your legend symbols did not match the panel 7, 8 and 9 graphs is wrong, please let me know. I'd like to track down any problems with -grc1leg2-. It would help if you provide the code so that I can try to replicate any problem you encounter.
          Last edited by Mead Over; 16 Mar 2022, 23:58.

          Comment


          • #6
            Hi Mead,
            Thank you for working on this great addition. My main problem with -grc1leg- was that using (y/x)size never worked, as well as other options to modify the combined graph. Now with the new -grc1leg2- it all works great!
            Thanks again!
            Nir

            Comment

            Working...
            X