Announcement

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

  • Matthew Holzmann
    started a topic Bar graph label to include "%" with value

    Bar graph label to include "%" with value

    I've been asked by powers that be to include the % symbol with blabel(bar) option in a graph bar (asis). I've been spinning wheels for hours googling and playing with gr_edit code, but can't seem to find the right logic. Help/suggestions would be greatly appreciated!

    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input float(order sfh_q1 sfh_q2 sfh_q3 sfh_q4 sfh_ytd) str4 measure
    1 100 100  80 . 97 "cat1"
    2  97  98 100 . 98 "cat2"
    3 100  98 100 . 99 "cat3"
    4 100  99 100 . 99 "cat4"
    5  98  98  93 . 97 "cat5"
    6 100  98 100 . 99 "cat6"
    7  99  96  97 . 97 "cat7"
    end
    graph bar (asis) sfh_q1 sfh_q2 sfh_q3 sfh_q4 sfh_ytd, over(measure, sort(order) gap(*2.5) label(angle() labsize(tiny))) blabel(bar, position(center) orientation(vertical) size(vsmall) color(white)) bar(1, color(pink)) bar(2, color(ltblue)) bar(3, color(navy)) yline(85, lwidth(vthin) lcolor(black)) ytitle(Percent (%), size(vsmall)) ylabel(0(10)100, labsize(tiny) angle(horizontal) glcolor(gs14) gmax) ymtick(##2) legend(col(5) size(vsmall)) graphregion(fcolor(gs14))
    Attached Files

  • Nick Cox
    replied
    Your "powers that be" are, I have to say, misguided although there may be difficulties in telling them so. An axis title percent (%) already says this twice.
    A tactic in such cases is to prepare two versions and suggest that one works better any way. Or prepare two versions any way. Any reviewer worth their salt will suggest the simpler version without percents on every bar and knowing the code for that in advance will make it easier to fix this a few months down the line when your bosses tell you to fix it.

    You may also have reasons for being coy about what is being shown, but categories cat1 to cat5 could hardly be less cryptic or enticing.

    A quite different suggestion is that it is hard work comparing lots of bars that are 100% or nearly so. Why not plot the complementary fractions? I see 0 1 2 3 4 7 and 20% as complementary and the research question is surely first of all about the 20%? Which one is it and does it make sense?

    Alternatively, use graph dot instead with exclude0 as an option.
    Last edited by Nick Cox; 27 Sep 2019, 01:10.

    Leave a comment:


  • Andrew Musau
    replied
    For non-default bar labels, you will want to switch to twoway bar (search the forum for examples). Graph editor aside, the only way you introduce additional labels to the bars is by using the -text()- option. If you are determined to do this in graph bar, you can start with the following rough sketch and delete/ adjust the (x,y) coordinates.

    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input float(order sfh_q1 sfh_q2 sfh_q3 sfh_q4 sfh_ytd) str4 measure
    1 100 100  80 . 97 "cat1"
    2  97  98 100 . 98 "cat2"
    3 100  98 100 . 99 "cat3"
    4 100  99 100 . 99 "cat4"
    5  98  98  93 . 97 "cat5"
    6 100  98 100 . 99 "cat6"
    7  99  96  97 . 97 "cat7"
    end
    
    forval i=1.5(2.3)100{
    local mytext `mytext' text(45 `i' "%", color(white) orientation(vertical) size(small))
    }
    graph bar (asis) sfh_q1 sfh_q2 sfh_q3 sfh_q4 sfh_ytd, over(measure, sort(order) gap(*2.5) label(angle() labsize(tiny))) blabel(bar, position(base) gap(30) orientation(vertical) size(vsmall) color(white)) bar(1, color(pink)) bar(2, color(ltblue)) bar(3, color(navy)) yline(85, lwidth(vthin) lcolor(black)) ytitle(Percent (%), size(vsmall)) ylabel(0(10)100, labsize(tiny) angle(horizontal) glcolor(gs14) gmax) ymtick(##2) legend(col(5) size(vsmall)) graphregion(fcolor(gs14)) `mytext'

    Click image for larger version

Name:	Graph.png
Views:	1
Size:	34.0 KB
ID:	1518074



    The first set of bars seem fine, but you need to adjust the positions leftwards or rightwards for the majority (perhaps also downwards for those with 2 digits). The loop creates the set of texts, which you can view as

    Code:
     di `"`mytext'"'

    text(45 1.5 "%", color(white) orientation(vertical) size(small)) text(45 3.8 "%", color(white) orientation(vertical) size(small)) text(45 6.1 "%", color(white) orientation(vertical) size(small)) text(45 8.399999999999999 "%", colo
    > r(white) orientation(vertical) size(small)) text(45 10.7 "%", color(white) orientation(vertical) size(small)) text(45 13 "%", color(white) orientation(vertical) size(small)) text(45 15.3 "%", color(white) orientation(vertical) s
    > ize(small)) text(45 17.6 "%", color(white) orientation(vertical) size(small)) text(45 19.9 "%", color(white) orientation(vertical) size(small)) text(45 22.2 "%", color(white) orientation(vertical) size(small)) text(45 24.5 "%",
    > color(white) orientation(vertical) size(small)) text(45 26.8 "%", color(white) orientation(vertical) size(small)) text(45 29.1 "%", color(white) orientation(vertical) size(small)) text(45 31.40000000000001 "%", color(white) orie
    > ntation(vertical) size(small)) text(45 33.7 "%", color(white) orientation(vertical) size(small)) text(45 36 "%", color(white) orientation(vertical) size(small)) text(45 38.3 "%", color(white) orientation(vertical) size(small)) t
    > ext(45 40.59999999999999 "%", color(white) orientation(vertical) size(small)) text(45 42.89999999999999 "%", color(white) orientation(vertical) size(small)) text(45 45.19999999999999 "%", color(white) orientation(vertical) size(
    > small)) text(45 47.49999999999999 "%", color(white) orientation(vertical) size(small)) text(45 49.79999999999998 "%", color(white) orientation(vertical) size(small)) text(45 52.09999999999998 "%", color(white) orientation(vertic
    > al) size(small)) text(45 54.39999999999998 "%", color(white) orientation(vertical) size(small)) text(45 56.69999999999997 "%", color(white) orientation(vertical) size(small)) text(45 58.99999999999997 "%", color(white) orientati
    > on(vertical) size(small)) text(45 61.29999999999997 "%", color(white) orientation(vertical) size(small)) text(45 63.59999999999997 "%", color(white) orientation(vertical) size(small)) text(45 65.89999999999996 "%", color(white)
    > orientation(vertical) size(small)) text(45 68.19999999999996 "%", color(white) orientation(vertical) size(small)) text(45 70.49999999999996 "%", color(white) orientation(vertical) size(small)) text(45 72.79999999999995 "%", colo
    > r(white) orientation(vertical) size(small)) text(45 75.09999999999995 "%", color(white) orientation(vertical) size(small)) text(45 77.39999999999995 "%", color(white) orientation(vertical) size(small)) text(45 79.69999999999995
    > "%", color(white) orientation(vertical) size(small)) text(45 81.99999999999994 "%", color(white) orientation(vertical) size(small)) text(45 84.29999999999994 "%", color(white) orientation(vertical) size(small)) text(45 86.599999
    > 99999994 "%", color(white) orientation(vertical) size(small)) text(45 88.89999999999993 "%", color(white) orientation(vertical) size(small)) text(45 91.19999999999993 "%", color(white) orientation(vertical) size(small)) text(45
    > 93.49999999999993 "%", color(white) orientation(vertical) size(small)) text(45 95.79999999999993 "%", color(white) orientation(vertical) size(small)) text(45 98.09999999999992 "%", color(white) orientation(vertical) size(small))

    The text in red corresponds to the positions of "%" in the first 3 bars. Some will be redundant as you have spaces between bars.
    Last edited by Andrew Musau; 26 Sep 2019, 14:58.

    Leave a comment:


  • Red Owl
    replied
    Below is some do-file code extracted from a post by Phil Clayton to the old Statalist (11 May 2012). This may be useful to you conceptually in developing your own code.
    Code:
    sysuse auto, clear
    graph bar (mean) foreign, over(rep78) blabel(bar) ///
        ytitle(% foreign) ylab(0 .2 "20" .4 "40" .6 "60" .8 "80" 1 "100")
    
    * for each level of rep78, replace the proportion in the bar label with a %
    foreach rep of numlist 1/5 {
        sum foreign if rep78==`rep', meanonly
        local lab: di %1.0f 100*r(mean)
        _gm_edit .Graph.plotregion1.barlabels[`rep'].text = {}
        _gm_edit .Graph.plotregion1.barlabels[`rep'].text.Arrpush `lab'%
    }
    
    * now re-draw the graph with the new labels
    graph display Graph
    Red Owl
    Stata/IC 16.0 (Windows 10, 64-bit)

    Leave a comment:


  • Matthew Holzmann
    replied
    I know there is code loop formatting to do this. What I have so far is:

    Code:
    local x=1
    local vlist sfh_q1-sfh_ytd
    
    foreach var in local vlist {
        
        local a1 = string(r(N), "3.0g") + "%"
    
        gr_edit plotregion1.barlabels[`x'].text = {}
        gr_edit plotregion1.barlabels[`x'].text.Arrpush `" `a1' "'
        local ++x
    
    }
    but this will only work for the first 2 bars, and only label with"%" for that matter.

    What am I not thinking of?

    Leave a comment:

Working...
X