Announcement

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

  • Inserting percentages on top of dots in dot chart

    Hi All,

    I am encountering some challenges in inserting percentage figures on top of dots that I created in a dot graph. I want each dot to have a corresponding percentage on top of it so that one can easily see what each dot represent in numbers (e.g. 0.8%, etc). I have used the code below to generate the attached graph and was hoping someone can guide me on how to do this. Also, I want to move the y-axis to the right. I have also added a sample of my data which might not be very useful as I have over 400,000 cases in my data and a sample only produces output for one country

    Code:
    graph dot cata10_IP_tot cata40_IP_tot cata10_OP_tot cata40_OP_tot cata10_drug_tot cata40_drug_tot [pw=popweight], over (ID, label(labsize(medsmall))) ylabel(0.00(.1)1.0) b1title("OOP drivers for proprtion of households incurring CATA10 & CATA40", size(small)) legend(rows(2) label(1 "Inpatient(CATA10)") label(2 "Inpatient(CATA40)") label(3 "Outpatient(CATA10)") label(4 "Outpatient(CATA10)") label(5 "Medicines(CATA10)") label(6 "Medicines(CATA40)")) legend(size(small)) plotregion(style(none))graphregion(color(white))title("Drivers of Out-of-pocket among households incurring CATA10 AND CATA40", lwidth(medthin) lpattern(solid) alignment(default) size(medsmall) color(black))
    Click image for larger version

Name:	Graph.png
Views:	2
Size:	34.0 KB
ID:	1433559

    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input float(cata10_IP_tot cata40_IP_tot cata10_OP_tot cata40_OP_tot cata10_drug_tot cata40_drug_tot popweight) str3 ID
    1 1 1 1 0 0 526.79333 "SLE"
    1 . 1 . 1 .  376.2809 "SLE"
    . 1 . 0 . 0  602.0495 "SLE"
    1 1 0 0 1 1  319.7159 "SLE"
    1 1 1 1 1 1 287.74432 "SLE"
    . . . . . .  383.6591 "SLE"
    1 1 1 1 0 0  883.6532 "SLE"
    . . . . . .  411.6399 "SLE"
    . . . . . .  824.0386 "SLE"
    1 . 0 . 0 . 1164.2126 "SLE"
    . 1 . 0 . 0  665.2644 "SLE"
    1 . 1 . 0 .  332.6322 "SLE"
    . . . . . .  288.6878 "SLE"
    . . . . . .  723.2624 "SLE"
    . . . . . .  542.4468 "SLE"
    . . . . . .  866.0634 "SLE"
    . . . . . .   509.268 "SLE"
    . . . . . . 1627.3403 "SLE"
    1 1 1 1 1 1  565.4721 "SLE"
    1 1 1 1 1 1  471.2268 "SLE"
    . . . . . .  471.2268 "SLE"
    . . . . . .   891.219 "SLE"
    1 1 0 0 1 1  565.4721 "SLE"
    1 1 0 0 1 1  505.7383 "SLE"
    1 1 0 0 1 1  590.0281 "SLE"
    . . . . . .  505.7383 "SLE"
    1 1 1 1 1 1   509.268 "SLE"
    1 1 1 1 1 1  1496.141 "SLE"
    0 0 0 0 1 1 1043.2982 "SLE"
    . . . . . .   745.213 "SLE"
    1 1 1 1 1 1  832.7753 "SLE"
    1 1 1 1 1 1  873.7015 "SLE"
    . 1 . 0 . 0  652.2204 "SLE"
    1 1 1 1 1 1  1325.212 "SLE"
    . . . . . . 1197.4375 "SLE"
    1 . 0 . 0 .  1630.551 "SLE"
    . . . . . .  4589.212 "SLE"
    1 . 1 . 1 .  776.0182 "SLE"
    . 1 . 1 . 1   434.576 "SLE"
    1 1 0 0 1 1   760.508 "SLE"
    . . . . . .   667.775 "SLE"
    . . . . . .   799.292 "SLE"
    . . . . . .   434.576 "SLE"
    . . . . . .    801.33 "SLE"
    1 . 1 . 1 .  702.2004 "SLE"
    . . . . . .  591.9625 "SLE"
    1 . 1 . 1 .    947.14 "SLE"
    1 1 0 0 0 0  242.1254 "SLE"
    . . . . . . 351.54935 "SLE"
    1 . 1 . 0 .  703.0987 "SLE"
    1 . 0 . 1 .   82.0824 "SLE"
    1 . 1 . 1 .  351.9786 "SLE"
    1 1 0 0 1 1   589.737 "SLE"
    . . . . . .  924.9821 "SLE"
    . . . . . . 1057.1224 "SLE"
    1 1 1 1 1 1 1056.8464 "SLE"
    . . . . . .  660.5291 "SLE"
    1 . 0 . 1 . 132.88681 "SLE"
    . . . . . .  446.3728 "SLE"
    . . . . . .  223.1864 "SLE"
    . . . . . .  707.6844 "SLE"
    1 . 1 . 1 .   588.373 "SLE"
    1 . 1 . 1 .   588.373 "SLE"
    . . . . . . 1429.7406 "SLE"
    . . . . . . 1668.0308 "SLE"
    1 1 0 0 1 1  706.0476 "SLE"
    1 1 1 1 1 1    391.74 "SLE"
    1 1 0 0 1 1  888.8264 "SLE"
    1 1 1 1 1 1   632.173 "SLE"
    1 1 0 0 1 1   810.425 "SLE"
    1 1 0 0 1 1  95.91477 "SLE"
    1 1 0 0 1 1 1310.0814 "SLE"
    1 . 1 . 1 .  396.8118 "SLE"
    . . . . . .  989.6385 "SLE"
    . . . . . . 1146.9276 "SLE"
    . . . . . . 1292.7937 "SLE"
    . . . . . .  1363.478 "SLE"
    . . . . . . 1090.7823 "SLE"
    1 1 1 1 1 1  954.4346 "SLE"
    . . . . . .  1363.248 "SLE"
    . . . . . .  1363.248 "SLE"
    1 1 1 1 1 1 1514.2296 "SLE"
    1 1 0 0 1 1  955.5792 "SLE"
    1 1 0 0 1 1  682.5565 "SLE"
    1 1 1 1 1 1  955.5792 "SLE"
    . . . . . . 1215.5759 "SLE"
    . . . . . .   585.167 "SLE"
    1 1 1 1 0 0   402.842 "SLE"
    . . . . . . 297.15637 "SLE"
    1 1 0 0 1 1  668.6018 "SLE"
    1 . 1 . 1 .  742.8909 "SLE"
    1 1 0 0 1 1 594.31274 "SLE"
    1 . 0 . 1 .  922.0376 "SLE"
    1 1 1 1 1 1   308.241 "SLE"
    1 1 1 1 1 1  693.5423 "SLE"
    1 . 0 . 1 .  876.8055 "SLE"
    . 1 . 1 . 1   1578.25 "SLE"
    . . . . . . 1402.8888 "SLE"
    1 1 0 0 1 1  1205.443 "SLE"
    . . . . . .  214.8361 "SLE"
    end
    Attached Files
    Last edited by Michal Onah; 08 Mar 2018, 23:58.

  • #2
    Various problems here of different sizes.

    First off, it's hard to read your code, so here it is again made a bit easier for others to read.

    Code:
    graph dot cata10_IP_tot cata40_IP_tot cata10_OP_tot cata40_OP_tot cata10_drug_tot cata40_drug_tot ///
    [pw=popweight], over (ID, label(labsize(medsmall))) ///
    ylabel(0.00(.1)1.0) ///
    b1title("OOP drivers for proprtion of households incurring CATA10 & CATA40", size(small)) ///
    legend(rows(2) label(1 "Inpatient(CATA10)") label(2 "Inpatient(CATA40)") label(3 "Outpatient(CATA10)") label(4 "Outpatient(CATA10)") label(5 "Medicines(CATA10)") label(6 "Medicines(CATA40)")) legend(size(small)) ///
    plotregion(style(none)) graphregion(color(white))   ///
    title("Drivers of Out-of-pocket among households incurring CATA10 AND CATA40", lwidth(medthin) lpattern(solid) alignment(default) size(medsmall) color(black))
    So the essence (better explained directly in similar words) is that you want to show means for 6 variables and 10 countries on a dot chart and to show the numbers too.

    The data example shows the form of the data but doesn't help us play with the graph as it is just some of the data for one country. The dataset is indeed too big to show here, but applying collapse would yield a dataset of 60 numbers that you could show us. (collapse allows pweights too.)

    I think the biggest deal here is that while your design is easy to understand in principle -- the encoding isn't a puzzle -- you're totally reliant on readers' willingness to pore over the legend and go back and forth between the legend and the graph -- the decoding will for most people be too much like hard work. You could tinker with the design. The first step could be varying the markers (so that they're not all ms(O) and you're totally dependent on people's ability to distinguish diferent colours). But you can't improve the design that much.

    I am going to suggest something else where you can easily show numbers too. I need to invent a problem of similar complexity. If (and only if) you show your complete data as suggested above, then the code can be translated to show you.

    Token code first.


    Code:
    * first, we create sandbox dataset to play with 
    clear 
    set obs 10 
    gen where = word("`c(ALPHA)'", _n) 
    
    set seed 2803 
    
    gen y1 = 100 * runiform() 
    
    forval j = 2/6 { 
       scalar multiplier = .4 + .2 * runiform()
       gen y`j' = y1 * multiplier 
    } 
    
    * easier going with a reshaped set 
    reshape long y, i(where) j(which) 
    
    * you need to define panel labels: don't make them too long 
    label define which 1 "Longer text" 2 "More text" 3 "And so on"
    label val which which 
    
    * alphabetical order is for dictionaries; choose a more meaningful order 
    bysort which (y) : gen rank = _n if which == 1
    bysort where (which) : replace rank = rank[1] 
    
    * this won't work unless if you install labmask from Stata Journal 
    * -search labmask, sj- for download location
    labmask rank, values(where) 
    gen show = string(y, "%2.0f") 
    
    graph twoway scatter rank y , by(which, note("") legend(off) ) ///
    yla(1/10, valuelabel ang(h) tlength(0)) ms(Oh) mc(orange)  ///
    || scatter rank y, ms(none) mlabel(show) mlabcolor(blue) ytitle("") xtitle("")
    Click image for larger version

Name:	michal.png
Views:	1
Size:	49.6 KB
ID:	1433587

    Some key points.

    1. Don't use alphabetical order There has to be a better order. Here I used rank on the first variable and it works beautifully because in the sandbox all other variables are just multiples of the first. You won't be so lucky.

    2. You can add numbers to graph dot at least in a limited sense (the option blabel(bar) works, even though it's not documented) but adding numbers to your design will make it worse. For example you have 4 means close together for SLE (Sierra Leone?): how will adding numbers work there?

    3. Working on percent scale makes the numbers easier to show on the graph (and no harder to understand). So, 14 as a percent takes up less space than .14 or 0.14.

    4. Here you could just dispense with the markers if you show the numbers.

    Comment


    • #3
      Originally posted by Nick Cox View Post
      Various problems here of different sizes.
      Hi Nick,

      Many thanks for your feedback and apologies for the delayed reply (flu season is back here). I have since resolved the issue I was having. Thanks again fr your invaluable assistance always!!

      Comment

      Working...
      X