Announcement

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

  • How to add braces to graphs in Stata

    Dear Statalisters,

    Are you aware of any approach to achieve the following result in Stata?

    Click image for larger version

Name:	braces.jpg
Views:	1
Size:	23.5 KB
ID:	1425539


    Basically, I want to generate a scatter plot and wanted to define right braces to highlight a specific set of observations. In the example above, we have two right braces that have been added manually.

    I will be extremely thankful for any help.

    All the best,

    Tiago
    Attached Files

  • #2
    Hi Tiago,

    Unfortunately, I'm not with "my" Stata at this very moment. Howver, since you haven't got any reply so far, I wonder whether the option - text() - from "added_text_options", boosted with a huge font size, wouldn't do the trick for you.
    Best regards,

    Marcos

    Comment


    • #3
      Thank you, Marcos.

      Indeed, the idea of using the text option with a very large font was my first attempt prior to posting here. The main problem with that approach is that brackets become very dissimilar in width.

      All the best,

      Tiago

      Comment


      • #4
        Tiago Pereira Another option is to use the marker labels for a scatter point on the graph at the place where you want the brace and size the maker label "}" as size(vhuge), this helps with controlling the relative size/position of the brace. {see the blue and green braces below}

        If you want to tinker with text box options, one way to get a bigger curly brace than the size(vhuge) is to build it using unicode text pieces from http://www.unicode.org/charts/ (there are unicode options for building arrows and boxes piece by piece). {see the purple curly brace built from several unicode characters below}

        Finally, I tend to just find a symbol that is large and include that to point to areas on the graph and label them {see the gold/orange examples below}

        (I'm assuming Stata 15 with these unicode examples)
        HTH



        Code:
        sysuse auto, clear
        
        su price, d
         g x1 = price if price == `r(p10)'
        g x2 = price if price == `r(p95)'
        
        g y1 = "}"  if !mi(x1)|!mi(x2)
        
        
        
        twoway (scatter price mpg)  ///
        (scatter x1 mpg, msymbol(point) mlabel(y1) mlabsize(vhuge) mlabcolor(blue) mlabposition(0)) ///
        (scatter x2 mpg, msymbol(point) mlabel(y1) mlabsize(vhuge) mlabcolor(green) mlabposition(0)) ///
        , text(4200 37  "}" , size(vhuge) color(red) ) ///
        text( 10000 27  "`=ustrunescape("\u23AB")'" "`=ustrunescape("\u23AC")'"  "`=ustrunescape("\u23AD")'" , size(vhuge) color(purple)) ///
        text( 1500 18 "`=ustrunescape("\u2B45")' No Data here!", size(large) color(gold)) ///
        text( 500 18 `"     `=ustrunescape("\u2B45")' Here's some info"', size(large) color(gold)) ///
        text( 5300 34.5 `"  Median is: `r(p50)'"'  , size(medlarge) color(orange))  ///
        text( 4800 30 "`=ustrunescape("\u21AF")'"  , size(huge) color(orange))
        ​​​​​
        Click image for larger version

Name:	Graph.png
Views:	1
Size:	134.7 KB
ID:	1425611

        Eric A. Booth
        Senior Research Scientist, Gibson Consulting Group

        eric.a.booth@gmail.com | http://www.eric-a-booth.com

        Comment


        • #5
          Thank you so much, Eric. Extremely helpful tip!

          Do you envisage a way to get those unicode text pieces working for Stata 14?

          All the best,

          Tiago

          Comment


          • #6
            Click image for larger version

Name:	test.png
Views:	1
Size:	57.5 KB
ID:	1425755

            First, update your Stata 14. Depending on the UTF-8 characters you want you need a font which support the character. Even if the rendering of the gph is not showing the characters, you may find that exporting to svg correctly represents the characters, and the free svg program inkshape can be used to convert to other formats. (The same strategy will be usefull also for version 15).
            Code:
            version 14.2
            
            * ref http://www.fileformat.info/info/unicode/char/23ac/index.htm
            
            /*
                U+23AA CURLY BRACKET EXTENSION    
                U+23AB (U+23A7) RIGHT (LEFT) CURLY BRACKET UPPER HOOK
                U+23AC (U+23A8) RIGHT (LEFT) CURLY BRACKET MIDDLE PIECE    
                U+23AD (U+23A9) RIGHT (LEFT) CURLY BRACKET LOWER HOOK    
            */
            
            local size 10
            local x .65
            local fnt `" fontface "Symbola" "'
            
            local RCBcol "navy"
            local LCBcol "blue"
            
            #delim ;
            
            tw scatteri .5 .5 ,
            
                m(diamond_hollow)
                msize(huge)
                ylab( 0(.1)1 , grid gmax)
                xlab(0(.1)1 , grid gmax)  
            
                /* the clock is ticking */
                
                text( .75 .2 `"{`fnt': `=ustrunescape("\u23F0")' }"' , size(30) color("red") )
                text( .25 .2 `"{`fnt': `=ustrunescape("\u23F3")' }"' , size(30) )
            
                /* play with U23A */
            
                text( 0.5 `= `x' - .05 '
            
                    "`=ustrunescape("\u23A7")'" /* LCB UPPER HOOK   */
                    "`=ustrunescape("\u23A8")'" /* LCB MIDDLE PIECE */
                    "`=ustrunescape("\u23A9")'" /* LCB LOWER HOOK   */  
                    
                    , size(`size') color("`LCBcol'")
                )
            
                text( 0.5 `x'
            
                    "`=ustrunescape("\u23AB")'" /* RCB UPPER HOOK   */
                    "`=ustrunescape("\u23AC")'" /* RCB MIDDLE PIECE */
                    "`=ustrunescape("\u23AD")'" /* RCB LOWER HOOK   */  
            
                    , size(`size') color("`RCBcol'")
            
                )
            
                text( 0.5 `= `x' + .2 '
            
                    "`=ustrunescape("\u23AB")'" /* RCB UPPER HOOK   */
                    "`=ustrunescape("\u23AA")'" /* RCB EXTENSION    */
                    "`=ustrunescape("\u23AA")'" /* RCB EXTENSION    */
                    "`=ustrunescape("\u23AC")'" /* RCB MIDDLE PIECE */    
                    "`=ustrunescape("\u23AA")'" /* RCB EXTENSION    */
                    "`=ustrunescape("\u23AA")'" /* RCB EXTENSION    */
                    "`=ustrunescape("\u23AD")'" /* RCB LOWER HOOK   */
            
                    , size(10)  color("`RCBcol'")
                )
            
                yline(.5 , lw(vthin))
            
                scheme(economist)    
            
                tit( "Stata/MP `c(version)' for Windows (64-bit x86-64)"
                     "Revision `c(born_date)' " ,
                     size(small)
                )
            ;
            
            #delim cr
            
            gr export "test.svg" , replace
            
            ********************************************************************************
            * convert svg to pdf, emf, eps using inkscape
            *
            * https://inkscape.org/sk/doc/inkscape-man.html
            ********************************************************************************
            
            local inkscape = `" "C:\Program Files\Inkscape\inkscape.exe" "'
            local svg "C:\Users\baa\Documents\test.svg"
            local fn "C:\Users\baa\Documents\test"
            
            confirm file `inkscape'    
            confirm file `svg'  
            
            capt erase "`fn'.pdf"
            capt erase "`fn'.emf"
            capt erase "`fn'.eps"
            capt erase "`fn'.png"
            
            sh `inkscape' `svg' --without-gui --export-pdf `fn'.pdf
            sh `inkscape' `svg' --without-gui --export-emf `fn'.emf
            sh `inkscape' `svg' --without-gui --export-eps `fn'.eps
            sh `inkscape' `svg' --without-gui --export-dpi=300 --export-png  "`fn'.png"
            
            confirm file "`fn'.pdf"
            confirm file "`fn'.emf"
            confirm file "`fn'.eps"
            confirm file "`fn'.png"
             
            exit
            Last edited by Bjarte Aagnes; 15 Jan 2018, 04:45.

            Comment


            • #7
              In my opinion, it is often simpler to just add the brace in an external program (e.g. Paint) than twisting Stata to do it, but of course it depends on how often you need to do this.

              Comment


              • #8
                Many thanks to Marcos, Eric, Bjartes and Jesse.

                Extremey helpful insights. I could make it work in my current graphs.

                Fully agree with Jesse's view, but in my case I will be generating dozens of similar graphs. Had I to rely on a manual approach, that would take a lot of time.

                Thanks again.

                All the best,

                Tiago

                Comment


                • #9
                  Dear Tiago,

                  the following does not draw the braces, but is an alternative way of addressing your task of outlining some of the observation points. This could be easier to configure and maintain if the input data for your chart changes.

                  Best, Sergiy Radyakin


                  Code:
                  clear all
                  sysuse auto
                  
                  generate mc=inrange(length,190,208) & inrange(weight,3000,3700)
                  generate trk=inrange(length,168,175) & inrange(weight,3100,3500)
                  
                  twoway scatter weight length if mc, color(orange) ms(X) ///
                      || scatter weight length if trk, color(navy) ms(T) ///
                      || scatter weight length if !mc & !trk, color(green) ms(oh) ///
                      scale(0.75) legend(rows(1) ///
                      label(1 "middle class cars") label(2 "trucks") label(3 "other cars")) ///
                      name(G1)
                  
                  twoway  scatteri 3000 190 3000 208 3700 208 3700 190 3000 190, ///
                          recast(area) nodropbase fc(yellow) lc(orange) || ///
                          scatteri 3100 168 3100 175 3500 175 3500 168 3100 168, ///
                          recast(area) nodropbase fc(cyan) lc(navy) || ///
                          scatter weight length, scale(0.5) color(maroon) ///
                          legend(rows(1) order(3) label(3 "cars")) ///
                          text(3500 168 "trucks", place(ne) color(navy)) ///
                          text(3700 190 "middle class cars", place(ne) color(orange)) ///
                          name(G2)
                  Click image for larger version

Name:	g1.png
Views:	1
Size:	35.9 KB
ID:	1426016
                  Click image for larger version

Name:	g2.png
Views:	1
Size:	30.5 KB
ID:	1426017

                  Comment


                  • #10
                    Dear Sergiy,

                    Your tip is extremely useful. Thank you!

                    All the best,

                    Tiago

                    Comment

                    Working...
                    X