Announcement

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

  • Graph Scatter for Each Point Conditional on Location

    Hi everyone,

    I am so close to figuring this out, yet feel so far. I would like to reproduce the following plot which has different colors depending on the quadrant (soc_graph_quad) that a point falls into:
    Click image for larger version

Name:	scowb_health_relevance.png
Views:	1
Size:	755.1 KB
ID:	1748206

    Unfortunately, the labels consistently overlap, so I would like to plot each point individually so that I could manually move them in the graph editor. I need to do this many times for different yet related domains, so I do not want to create a "position" variable that changes the position of the label for individual points.

    This is my data:


    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input float(socwb_health socwb_relevance soc_graph_quad socwb_labels)
     -.3139982  1.6270845 4  1
      1.949235  1.0825317 1  2
     .14476526   1.125838 1  3
     -.4975036   1.720457 4  4
     -.1916613   .9536769 4  5
     -.7421775    .558949 4  6
     1.0622922   .9521463 1  7
    -.25282976   .6484658 4  8
      .4811918  1.1118306 1  9
     .05301256   .7214679 1 10
    -.43633515   .6277263 4 11
    -1.2621094   .4262436 4 12
      .8482026   1.477142 1 13
     1.1540449   .8362689 1 14
     -1.996131  1.4378642 4 15
    -3.2500846 .023809524 4 16
    end
    label values socwb_relevance socwb
    label values socwb_labels socwb
    label def socwb 1 "Amount of contact with others", modify
    label def socwb 2 "People who are kind and respectful", modify
    label def socwb 3 "Feeling appreciated by others", modify
    label def socwb 4 "Sense of belonging", modify
    label def socwb 5 "Freedom to express my opinion", modify
    label def socwb 6 "People who help me feel calm", modify
    label def socwb 7 "People who accept me", modify
    label def socwb 8 "People who are accessible", modify
    label def socwb 9 "People who listen well", modify
    label def socwb 10 "Emotional support", modify
    label def socwb 11 "Practical support", modify
    label def socwb 12 "Support in trying new things", modify
    label def socwb 13 "Close friendships", modify
    label def socwb 14 "Caring for others", modify
    label def socwb 15 "Coping with relational conflict or challenges", modify
    label def socwb 16 "Other", modify
    label values soc_graph_quad graph_quad
    label def graph_quad 1 "Celebrate", modify
    label def graph_quad 4 "Prioritize", modify

    This is what I have tried so far, but it only results in one point getting plotted 16 times:

    Code:
    separate socwb_relevance, by(socwb_labels)
    separate socwb_health, by(socwb_labels)
    separate socwb_labels, by(socwb_labels)
    
    forvalues i=1/16{
    scatter socwb_relevance_all_`i' socwb_health_all_`i' if soc_graph_quad==1, mcolor("0 204 102") msize(2) mlabel(socwb_labels`i') ||scatter socwb_relevance_all_`i' socwb_health_all_`i' if soc_graph_quad==2, mcolor("0 154 193") msize(2) mlabel(socwb_labels`i')|| scatter socwb_relevance_all_`i' socwb_health_all_`i' if soc_graph_quad==3, mcolor("255 177 0") msize(2) mlabel(socwb_labels`i')|| scatter socwb_relevance_all_`i' socwb_health_all_`i' if soc_graph_quad==4, mcolor("235 0 83") msize(2) mlabel(socwb_labels`i') legend(col(4)) ytitle(Importance) xtitle(Health) yline(0, lpattern(dash) lcolor(black%90)) ylabel(-3(1)3) yscale(range(-1 1)) xline(0, lpattern(dash) lcolor(black%90)) xlabel(-3(1)3) xscale(range(-.5 .5)) title(Social Wellbeing)  graphregion(fcolor("239 242 251")) plotregion(fcolor(white)) scheme(s1color) mlabcolor(black) mlabsize(vsmall) legend(order(1 "Celebrate" 2 "Maintain" 3 "Review" 4 "Prioritize"))
    }
    I've seen Andrew Musau's code #3 here: https://www.statalist.org/forums/for...urs-in-pcspike and #2 here: https://www.statalist.org/forums/for...-a-observation that creates a local command macro to loop through categories, but I can't seem to create something similar to loop through all 16 points and the conditional quadrant coloring logic.

    Thank you,
    Ashleigh
    Last edited by Ashleigh Hope; 28 Mar 2024, 22:59. Reason: edit: accidentally attached graph .png twice.

  • #2
    I don't think you need to -separate- your data. This example uses Asjad Naqvi's white_tableau scheme (ssc desc schemepack).

    Code:
    local colorlist "green blue yellow red"
    forvalues i = 1/4{
        local a: word `i' of `colorlist'
        local gr scatter socwb_relevance socwb_health if soc_graph_quad == `i', mcolor(`a') mlabel( socwb_labels)  ||  `gr'
    }
    
    `gr' || , xlabel(-3(1)3) ylabel(-3(1)3) xline(0, lp(dash)) /// 
        yline(0 , lp(dash)) scheme(white_tableau) /// 
        legend(pos(6) row(1)) legend(pos(6) row(1) /// 
        order(1 "Celebrate" 2 "Maintain" 3 "Reivew" 4 "Prioritize") )
    Click image for larger version

Name:	Graph.png
Views:	1
Size:	75.4 KB
ID:	1748274

    Comment


    • #3
      I want to suggest something different, as I don't think this approach works very well. Here is the entire code, including your data example.

      labmask is from the Stata Journal.

      Many details could be varied here, according to taste and circumstance.

      Code:
      * Example generated by -dataex-. For more info, type help dataex
      
      * Example generated by -dataex-. For more info, type help dataex
      clear
      input float(socwb_health socwb_relevance soc_graph_quad socwb_labels)
       -.3139982  1.6270845 4  1
        1.949235  1.0825317 1  2
       .14476526   1.125838 1  3
       -.4975036   1.720457 4  4
       -.1916613   .9536769 4  5
       -.7421775    .558949 4  6
       1.0622922   .9521463 1  7
      -.25282976   .6484658 4  8
        .4811918  1.1118306 1  9
       .05301256   .7214679 1 10
      -.43633515   .6277263 4 11
      -1.2621094   .4262436 4 12
        .8482026   1.477142 1 13
       1.1540449   .8362689 1 14
       -1.996131  1.4378642 4 15
      -3.2500846 .023809524 4 16
      end
      label values socwb_relevance socwb
      label values socwb_labels socwb
      label def socwb 1 "Amount of contact with others", modify
      label def socwb 2 "People who are kind and respectful", modify
      label def socwb 3 "Feeling appreciated by others", modify
      label def socwb 4 "Sense of belonging", modify
      label def socwb 5 "Freedom to express my opinion", modify
      label def socwb 6 "People who help me feel calm", modify
      label def socwb 7 "People who accept me", modify
      label def socwb 8 "People who are accessible", modify
      label def socwb 9 "People who listen well", modify
      label def socwb 10 "Emotional support", modify
      label def socwb 11 "Practical support", modify
      label def socwb 12 "Support in trying new things", modify
      label def socwb 13 "Close friendships", modify
      label def socwb 14 "Caring for others", modify
      label def socwb 15 "Coping with relational conflict or challenges", modify
      label def socwb 16 "Other", modify
      label values soc_graph_quad graph_quad
      label def graph_quad 1 "Celebrate", modify
      label def graph_quad 4 "Prioritize", modify
      
      sort socwb_health 
      gen id = cond(socwb_health >= 0, _n + 2, _n)
      labmask id, values(socwb_labels) decode 
      
      twoway rspike socwb_health socwb_relevance id, horizontal lc(black) lw(thin) yla(1/9 12/18, valuelabel tlc(none)) ymla(19 "{bf:Celebrate}" 10 "{bf:Prioritize}", labsize(*2) tlc(none)) name(G1, replace) || scatter id socwb_health, mc(stc1) || scatter id socwb_relevance, mc(stc2)       legend(order(2 "health" 3 "relevance") row(1) pos(12)) ytitle("")  xli(0, lc(gs8) lw(vthin) lp(solid))

      Click image for larger version

Name:	celebrate_prioritize .png
Views:	1
Size:	82.8 KB
ID:	1748296

      Comment


      • #4
        Thank you both for your responses.

        Thanks to Stata 18's new colorvar feature (and a much needed update on my end) I was actually able to do what I needed. Praise be when using this option with two way graphs I can click on each value label and move them in position around the marker within the graph editor. I did also create a position variable based on quadrant, which starting out is helpful and then I only have to adjust a few marker labels.

        Scott, the code you provided is very similar to where I initially started this journey looping through the various conditions of my soc_quad_graph variable. However, this still resulted in markers being changed for all the points that fell within a given quadrant and not each individual one which is what I needed to prevent significant overlapping. Thank you for your response!

        In some cases, Nick I will have additional data in those bottom quadrants (see updated data), so I don't believe the plot you showed will work given the information I am trying to display is four-way. I do like this a lot for showing the absolute difference between two variables and will keep for future work. Thank you, greatly.

        My final code and resulting graph:

        Code:
        * Example generated by -dataex-. For more info, type help dataex
        clear
        input float(socwb_health socwb_relevance socwb_graph_quad socwb_labels socwb_quad_position)
          .4668226   .26016963 1  1 3
         2.0739164   1.3507328 1  2 3
         -.2219319 -.036589276 3  3 7
         -.6237053   1.3159038 4  4 1
         -.2219319   .11238942 4  5 1
         -.8532901   -1.100862 3  6 7
           .868596  -.25882155 2  7 5
         -.2219319  -1.1439303 3  8 7
          .5242188    -.715757 2  9 5
         .00765293   -.7590873 2 10 5
         -.3367243  -.07890859 3 11 7
        -1.0254788  -1.5249158 3 12 7
           .581615    1.792538 1 13 3
         1.0981809  -.25129396 2 14 5
        -2.1160066   1.0384316 4 15 1
        end
        label values socwb_graph_quad graph_quad
        label def graph_quad 1 "Celebrate", modify
        label def graph_quad 2 "Maintain", modify
        label def graph_quad 3 "Review", modify
        label def graph_quad 4 "Prioritize", modify
        label values socwb_labels socwb
        label def socwb 1 "Amount of contact with others", modify
        label def socwb 2 "People who are kind and respectful", modify
        label def socwb 3 "Feeling appreciated by others", modify
        label def socwb 4 "Sense of belonging", modify
        label def socwb 5 "Freedom to express my opinion", modify
        label def socwb 6 "People who help me feel calm", modify
        label def socwb 7 "People who accept me", modify
        label def socwb 8 "People who are accessible", modify
        label def socwb 9 "People who listen well", modify
        label def socwb 10 "Emotional support", modify
        label def socwb 11 "Practical support", modify
        label def socwb 12 "Support in trying new things", modify
        label def socwb 13 "Close friendships", modify
        label def socwb 14 "Caring for others", modify
        label def socwb 15 "Coping with relational conflict or challenges", modify

        Code:
        scatter socwb_relevance socwb_health , colorvar(socwb_graph_quad) colorlist("0 204 102" "0 154 193" "255 177 0" "235 0 83") msize(2) mlabel(socwb_labels) mlabvpos(socwb_quad_position) mlabangle(30) mlabgap(0) mlabcolor(black) mlabsize(vsmall) legend(col(4)) ytitle(Importance, size(large)) xtitle(Health, size(large)) yline(0, lpattern(dash) lcolor(black%90)) ylabel(-2.5(1)2.5) xline(0, lpattern(dash) lcolor(black%90)) xlabel(-2.5(1)2.5) title(Social Wellbeing, size(huge))  graphregion(fcolor("239 242 251")) plotregion(fcolor(white))  zscale(reverse noline)  ztitle("") zlab(, tlength(0) norescale valuelabel)
        Click image for larger version

Name:	socwb_importance_health.png
Views:	1
Size:	193.2 KB
ID:	1748787

        Last edited by Ashleigh Hope; 03 Apr 2024, 13:38. Reason: Updated formatting and typos.

        Comment

        Working...
        X