Announcement

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

  • multidot available on SSC

    Thanks to the ever-energetic Kit Baum, a new command multidot is now available on SSC for Stata 10 up.

    (It may even be portable to Stata 8 up, but I have not tried.)

    If you suddenly think you've read this before, you're remembering the announcement of multiline on Statalist in https://www.statalist.org/forums/for...ailable-on-ssc

    multidot is a cousin, or perhaps a sibling, of multiline, with similar aims but different details.

    Install with

    Code:
     
    ssc install multidot
    The main application of multidot is to plot dot charts or similar charts in separate panels, especially but not only for variables measured in different units or on very different scales.

    This can be a good alternative to a superimposed plot if the latter appears unclear or absurd. Alternatively, multidot is a direct solution for situations in which you would be tempted to produce separate graphs and follow with graph combine. That method is highly flexible, particularly combined with use of the Graph Editor, but you may still have to deal with challenges such as removing repeated material and keeping panels the same size.

    What multidot does is temporarily restructure the data so that different variables are different groups of a single response variable.

    Here is a first example:

    Code:
     
    sysuse auto, clear 
    
    set scheme s1color 
    
    multidot price mpg if foreign, over(make)
    
    multidot price mpg weight if foreign, over(make) recast(bar) desc by(row(1)) xla(, ang(v)) blcolor(blue)
    Click image for larger version

Name:	multidot1.png
Views:	1
Size:	40.2 KB
ID:	1403430

    The default dot chart is pushed at you partly out of a personal prejudice that such dot charts remain undersold, a few decades after they were promoted by William S. Cleveland in his papers and books. (The name Cleveland dot chart is sometimes used in an attempt to distinguish such charts from histogram-like dot plots.) In the case of both price and mpg, we don't need to see zero on the graph. The key comparisons are between cars, not with zero!

    Nevertheless, I suspect that users of this program may find themselves reaching for the recast(bar) option. The second multidot command above does that:

    Click image for larger version

Name:	multidot2.png
Views:	1
Size:	44.5 KB
ID:	1403431

    I am not especially pleased to reach for ang(v) but sometimes compromises are needed.

    Here's another example. I found some interesting data in an article in the Economist. They had a map with numeric data superimposed. Here are two bar charts.


    Code:
     
    clear
    input str13 country budget active reservists
    "United States" 604.5 1347 865
    "India" 51.1 1395 1155
    "China" 145.0 2183 510
    "Malaysia" 4.2 109 52
    "Singapore" 10.2 73 313
    "Vietnam" 4.0 482 5000
    "Indonesia" 8.2 396 400
    "Philippines" 2.5 125 131
    "Taiwan" 9.8 215 1657
    "S. Korea" 33.8 630 4500
    "Japan" 47.3 247 56
    "N. Korea" .  1190 600
    "Australia" 24.2 58 21
    end
    
    label var budget "Defence budget ($ billion)"
    label var active "Active forces ('000)"
    label var reservists "Reservists ('000)"
    note : "Source: The Economist, April 22 2017"
    note : "Their source: IISS, 2016"
    
    multidot b a r, over(c) by(row(1) compact) recast(hbar) subtitle(, size(medsmall)) ytitle("") missing  bfcolor(eltgreen)
    
    multidot a r b, over(c) by(row(1) compact) recast(hbar) subtitle(, size(medsmall)) ytitle("") xla(#5, labsize(small)) missing bfcolor(eltgreen)

    Click image for larger version

Name:	multidot3.png
Views:	1
Size:	28.0 KB
ID:	1403432


    Click image for larger version

Name:	multidot4.png
Views:	1
Size:	28.2 KB
ID:	1403433


    Although these graphs have the look and feel of those created with graph dot and graph hbar, they are created with twoway. As a courtesy to those familiar with graph hbar, multidot translates a call for hbar as a call for a (horizontal) application of twoway bar.

    More handles are explained in the help.

  • #2
    Hi Nick -
    Thanks for this command; I find it very helpful.
    After toying with the program I have a few questions that I couldnt figure out (and may not be possible/advisable within multidot):

    1. Is there a way to make the symbols a different shape (or color) in each of the panels?

    2. Is there a way to label the dots with something other than the variable in the over() option. It seems that the limitation I"m likely running into is probably necessary for the way you graph the data (that the data are collapsed/stacked in the background and so the other variable I'd like to label these dots by disappears) but I thought I'd check. Being able to label the dot by the varlist variable instead of the over variable would be helpful in most cases, or better being able to label the points with another variable (which sometimes just contains labels for a subset of the dots/points that I want to highlight/emphasize).

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

    Comment


    • #3
      Eric: Thanks very much for your interest.

      #1 I don't think so at present. I think that is programmable with an extra trick, but I would want a good argument for it.

      #2 There is an undocumented -show()- option left over from some early play. At this moment I am away from the code but that may help.

      Comment


      • #4
        For #1: My argument for different symbols/colors in the panels is just that I'd like to be able to highlight one or more of the panels as being different from the rest or to continue the dot scheme from other plots in my same paper/report (e.g., always using diamonds for middle schools and hollow circles for elementary schools in all figures in my report). In thinking this through, I dont think this is likely a compelling reason to add the functionality to multidot. Instead I should probably just (1) use twoway to construct these graphs manually or (2) create separate multidot plots by school type and then -graph combine- them.

        For #2: The show() option is helpful. In case others are interested here's the toy example I'm using to produce labels for a subset of datapoints using show():
        Code:
        sysuse auto, clear
        qui su trunk,d
        g trunk2 = "Trunk=" + string(trunk) if trunk>`r(p90)'
        multidot trunk mpg if trunk>`r(mean)', over(make ) sort(trunk) desc ///
        scheme(s1mono) by(row(1) compact) ///
        msy(O d Oh) mcolor(emidblue red) msize(medlarge small) ///
        xla( 0(25)100 ,ang(v)) blcolor(blue) ///
        fcolor(emidblue) bfcolor(emidblue) ///
        subtitle(, size(vsmall) color(emidblue) fcolor(gs13) ) ///
        ytitle("test") xvarformat(%9.1f) xline(25, lwidth(medium)) ///
        mlabsize(vsmall) mlabcolor(red) show(trunk2)
        
        
        **splitting within one variable with separate:
        sysuse auto, clear
        keep in 1/30
        g bin = int(runiform()*2)
        separate trunk, by(bin) short missing
        
        multidot trunk? , over(make ) desc miss ///
        scheme(s1mono) by(row(1) compact) ///
        msy(O d Oh) mcolor(emidblue red) msize(medlarge small) ///
        xla( 0(5)25 ,ang(v)) blcolor(blue) ///
        fcolor(emidblue) bfcolor(emidblue) ///
        subtitle(, size(vsmall) color(emidblue) fcolor(gs13) ) ///
        ytitle("test") xvarformat(%9.1f) xline(5, lwidth(medium)) ///
        mlabsize(vsmall) mlabcolor(red) show(trunk)
        Last edited by eric_a_booth; 24 Jul 2017, 11:42.
        Eric A. Booth | Senior Director of Research | Far Harbor | Austin TX

        Comment


        • #5
          Dear Eric,
          Following your suggestion and as Nick so far has not implemented the functionality, here is my very 'clunky' solution to get what you are looking for.
          But not that the automation of the manual editing of the graph window is always a solution particular to the case at hand:
          Code:
          **splitting within one variable with separate:
          sysuse auto, clear
          keep in 1/30
          g bin = int(runiform()*2)    // 0/1 values
          separate trunk, by(bin) short missing
          
          multidot trunk? , over(make) desc miss ///
          scheme(s1mono) by(row(1) compact) ///
          msy(oh) mcolor(emidblue red) msize(medlarge small) ///
          xla(0(5)25 , ang(v)) blcolor(blue) ///
          fcolor(emidblue) bfcolor(emidblue) ///
          subtitle(, size(vsmall) color(emidblue) fcolor(gs13) ) ///
          ytitle("test") xvarformat(%9.1f) xline(5, lwidth(medium)) ///
          mlabsize(vsmall) mlabcolor(red) show(trunk)
          * Loop the manual editing of the right panel symbol
          forvalue i = 1/14 {
          gr_edit plotregion1.plotregion1[2].plot1.EditCustomStyle , j(`i') style(marker(symbol(circle)))
          }
          You will then get this result:
          Click image for larger version

Name:	Tutorial_multidot_manual_symbol_editing.png
Views:	1
Size:	55.7 KB
ID:	1490963

          Happy graphing!
          http://publicationslist.org/eric.melse

          Comment


          • #6
            Thanks to Kit Baum as ever, multidot has been updated on SSC with extra options.

            separate specifies that data in different panels for the various yvars should be shown differently.
            There is then scope for specifying different marker symbols, marker colours, and so forth.

            sepby() specifies that data be shown differently according to the distinct values of the variable
            named. There is then scope for specifying different marker symbols, marker colours, and so forth.

            separate and sepby() may not be combined. sepby() option is not allowed with recast().

            Comment

            Working...
            X