Announcement

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

  • Controlling gaps between bars - twoway bar- and losing bars when specifying -xla(none)

    Hi all,

    I'm using Stata 13.1. I am trying to present my bar chart using twoway bar and then specifying -horizontal-. As there are only two categories in my data, I want to control the width of my bars so they look nicer aesthetically. However, when I specify the barwidth, I get a rather large gap between the two bars. I though -graph display- my offer some joy in reducing the gap between the two bars, but I havent because it changes the aspect so that the font is very small. Also -bargap- (bargap(0)) appears to have no effect on the graph.


    Another problem I seem to encounter is that I wish to remove the -xlabel- values from being presented (the main reason is that I am addiing the values at the end of each bar and so dont want to duplicate). However when I add -xla(none)-, I lose the bar of the bottom category. I've pasted too sets of code below - please note that the code includes use of -splitvallabels- (findit splitvallabels).
    Any help appreciated.


    *************BEGIN CODE

    clear
    #delimt ;
    set seed 339487731
    set obs 1
    g VNuAF_Strokes = floor(runiform() *100)
    g VNuAF_Strokes_NOAC = floor(VNuAF_Strokes * 0.95)-10
    g n = _n
    reshape long V, i(n) j(New_var) string
    g order = 2 if New_var =="NuAF_Strokes"
    replace order = 1 if New_var=="NuAF_Strokes_NOAC"
    sort order
    label define Order 2 "AF strokes in 2014/15:" 1 "AF strokes not on anticoagulation:"
    label values order Order

    gen V2 = V[2]
    gen V1 = V[1]

    list
    format %9.0gc V*
    gen mytext = ""
    qui forval j = 1/2 {
    summarize V`j' , meanonly
    replace mytext = string(r(max), "%9.0gc") in `j'
    }





    splitvallabels order, length(18) nob local(foo)
    su V, meanonly
    g a = `r(max)'
    #delim ;
    twoway bar V order if order == 2, horiz barw(0.2) bcolor("91 53 140") ||
    bar V order if order == 1, horiz barw(0.2) bcolor("0 148 218")
    legend(off) ysc(lc(none)) xsc(lc(none)) bargap(0)
    yla(`foo' , val noticks ang(h)) xla(0 (20) 100, format(%9.0gc) ang(h))
    ytitle("") xtitle("") plotregion(color(white)) ||
    sc order a, mlabel(mytext) mlabcolor(black) msymbol(i) mlabsize(medium) ;
    #delim cr





    ******************MISSING BAR FOLLOWING -xla(none)-

    clear
    #delimt ;
    set seed 339487731
    set obs 1
    g VNuAF_Strokes = floor(runiform() *100)
    g VNuAF_Strokes_NOAC = floor(VNuAF_Strokes * 0.95)-10
    g n = _n
    reshape long V, i(n) j(New_var) string
    g order = 2 if New_var =="NuAF_Strokes"
    replace order = 1 if New_var=="NuAF_Strokes_NOAC"
    sort order
    label define Order 2 "AF strokes in 2014/15:" 1 "AF strokes not on anticoagulation:"
    label values order Order

    gen V2 = V[2]
    gen V1 = V[1]

    list
    format %9.0gc V*
    gen mytext = ""
    qui forval j = 1/2 {
    summarize V`j' , meanonly
    replace mytext = string(r(max), "%9.0gc") in `j'
    }


    splitvallabels order, length(18) nob local(foo)
    su V, meanonly
    g a = `r(max)'
    #delim ;
    twoway bar V order if order == 2, horiz barw(0.2) bcolor("91 53 140") ||
    bar V order if order == 1, horiz barw(0.2) bcolor("0 148 218")
    legend(off) ysc(lc(none)) xsc(lc(none)) bargap(0)
    yla(`foo' , val noticks ang(h)) xla(none)
    ytitle("") xtitle("") plotregion(color(white)) ||
    sc order a, mlabel(mytext) mlabcolor(black) msymbol(i) mlabsize(medium) ;
    #delim cr

  • #2
    Thank you for an example that is almost reproducible. Only a small correction was necessary to run your code.
    Code:
    #delimt ;
    is not a valid command. It should be
    Code:
    #delimit ;
    but that command is misplaced before
    Code:
    set seed 339487731
    because the commands that follow are not delimited with a semicolon. The #delimit commands preceding the set commands must therefore be deleted.

    Now to your questions. Regarding the bar width, in help twoway bar it says:

    barwidth(#) specifies the width of the bar in xvar units. The default is width(1). When a bar is plotted, it is centered at x, so half the width extends below x and half above.
    You specified
    Code:
    barw(0.2)
    which means the bars are drawn with 20% of the default width. Instead, you could try
    Code:
    barw(0.95)
    Regarding the disappearing bar, that is odd and I cannot explain why this happens. However, you can trick Stata by replacing
    Code:
    xla(none)
    by
    Code:
    xla(0 " ", labsize(zero) notick)
    This option draws a blank character at 0 and no other labels, the label size is set to zero to reduce the margin below the graph, and the notick option suppresses the tick that would otherwise appear at 0. You can fine-tune the margin below the graph further with the graphregion(margin()) option, for example
    Code:
    graphregion(margin(4 4 3 4))
    Below is your code with my changes, tested in Stata 13.1 and Stata 14.0.
    Code:
    clear
    set seed 339487731
    set obs 1
    g VNuAF_Strokes = floor(runiform() *100)
    g VNuAF_Strokes_NOAC = floor(VNuAF_Strokes * 0.95)-10
    g n = _n
    reshape long V, i(n) j(New_var) string
    g order = 2 if New_var =="NuAF_Strokes"
    replace order = 1 if New_var=="NuAF_Strokes_NOAC"
    sort order
    label define Order 2 "AF strokes in 2014/15:" 1 "AF strokes not on anticoagulation:"
    label values order Order
    
    gen V2 = V[2]
    gen V1 = V[1]
    
    list
    format %9.0gc V*
    gen mytext = ""
    qui forval j = 1/2 {
    summarize V`j' , meanonly
    replace mytext = string(r(max), "%9.0gc") in `j'
    }
    
    
    splitvallabels order, length(18) nob local(foo)
    su V, meanonly
    g a = `r(max)'
    #delim ;
    twoway bar V order if order == 2, horiz barw(0.95) bcolor("91 53 140") ||
    bar V order if order == 1, horiz barw(0.95) bcolor("0 148 218")
    legend(off) ysc(lc(none)) xsc(lc(none)) bargap(0)
    yla(`foo' , val noticks ang(h)) xla(0 " ", labsize(zero) notick)
    ytitle("") xtitle("") plotregion(color(white)) ||
    sc order a, mlabel(mytext) mlabcolor(black) msymbol(i) mlabsize(medium) 
    graphregion(margin(4 4 3 4));
    #delim cr

    Comment


    • #3
      Hi Friedrich,

      Many thanks for your comments/corrections - I think I added the #delimit typo after pasting from Stata. The suggestions you have highlighted work nicely - as it happens I had just started to experiment with

      **
      xla(0 (20) 100, format(%9.0gc) noticks ang(h)) xla(0 " " 20 " " 40 " " 60 " " 80 " " 100 " ")
      ***

      However this is not as nice as your suggestion, and your suggestion actually allows me to not worry about the maximum scale. Visually I think I was hoping to shrink the size of the bars so that the graph area was a lot smaller. Perhaps this is a trick too much of Stata? I did take a look at -graph display- but didnt experiment long enough

      Thanks

      Tim

      Comment


      • #4
        Depending on what you are trying to accomplish, add one of the two options below to the graph command.

        Option 1: larger margins above and below the graph.
        Code:
        graphregion(margin(4 4 30 30))
        Option 2: smaller height and larger labels.
        Code:
        ysize(2) scale(2)

        Comment


        • #5
          Hi Friedrich,

          I'm trying to achieve something like this (in terms of proportions)

          Click image for larger version

Name:	Capture1.PNG
Views:	1
Size:	5.7 KB
ID:	1299835


          Thanks

          Tim

          Comment


          • #6
            Friedrich,

            Thanks for your help, I've had a play with the -graphregion- and I'm quite happy with this result


            clear
            set seed 339487731
            set obs 1
            g VNuAF_Strokes = floor(runiform() *100)
            g VNuAF_Strokes_NOAC = floor(VNuAF_Strokes * 0.95)-10
            g n = _n
            reshape long V, i(n) j(New_var) string
            g order = 2 if New_var =="NuAF_Strokes"
            replace order = 1 if New_var=="NuAF_Strokes_NOAC"
            sort order
            label define Order 2 "AF strokes in 2014/15:" 1 "AF strokes not on anticoagulation:"
            label values order Order

            gen V2 = V[2]
            gen V1 = V[1]

            list
            format %9.0gc V*
            gen mytext = ""
            qui forval j = 1/2 {
            summarize V`j' , meanonly
            replace mytext = string(r(max), "%9.0gc") in `j'
            }


            splitvallabels order, length(18) nob local(foo)
            su V, meanonly
            g a = `r(max)'
            #delim ;
            twoway bar V order if order == 2, horiz barw(0.85) bcolor("91 53 140") ||
            bar V order if order == 1, horiz barw(0.85) bcolor("0 148 218")
            legend(off) ysc(lc(none)) xsc(lc(none)) bargap(0)
            yla(1/2, val noticks ang(h)) xla(0 " ", labsize(zero) notick) xsc(range(0 `=r(max)+10'))
            ytitle("") xtitle("") plotregion(color(white)) ||
            sc order a, mlabel(mytext) mlabcolor(black) msymbol(i) mlabsize(medium)
            graphregion(margin(1 10 30 30)) ysize(2) scale(2);
            #delim cr

            Comment


            • #7
              You could also remove the gridlines by adding the nogrid option for the y-labels.
              Code:
              #delim ;
              twoway bar V order if order == 2, horiz barw(0.85) bcolor("91 53 140") ||
              bar V order if order == 1, horiz barw(0.85) bcolor("0 148 218")
              legend(off) ysc(lc(none)) xsc(lc(none)) bargap(0)
              yla(1/2, val noticks ang(h) nogrid) xla(0 " ", labsize(zero) notick) xsc(range(0 `=r(max)+10'))
              ytitle("") xtitle("") plotregion(color(none)) ||
              sc order a, mlabel(mytext) mlabcolor(black) msymbol(i) mlabsize(medium)
              graphregion(margin(1 10 30 30)) ysize(2) scale(2);
              #delim cr

              Comment

              Working...
              X