Announcement

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

  • different yline/subtitle in a by() plot

    Hi all!

    I have a complicated graph that I have multiples of for different categories and would like to simplify slightly by using the , by() feature of the graphing tools to get everything in a single image (rather than creating a separate image for each category).

    I would like to display the mean for each category using text and a simple yline, but am unsure how to go about this.

    The following code creates a simple version of what I'm after, but I'd like the mean value for each subtype to be displayed (or used to create a yline).

    I've been searching for ages, and trying different combinations of things, but so far to no avail!

    Thank you kindly,
    Simon.

    Code:
    sysuse auto, clear
    
    twoway scatter price mpg, by(foreign) ///
        subtitle("Mean price: <insert mean for subtype here> ", suffix ring(0) pos(1) nobexpand fcol(none) lcol(white))
        yline() // with a value inside the yline brackets equal to the mean for the relevant subtype

  • #2
    I don't know a way to get different yline() calls in different panels. What you want I think needs a separate variable or indeed variables to be created. This code could be made simpler for your example, but equally your example isn't one you care about, so I have added some generality to cope (e.g.) with missing values.

    Points of importance.

    1. To mimic yline() calls you need to plot a variable that is constant versus one that isn't, lay down the line graph before the scatter graph and tune the line presentation (colour, width, etc.).

    2. One approach, which I like, is draw the line only over the observed range of the horizontal variable in each panel.

    3. Another approach, which I like too, is to draw the line over the same horizontal range, which you must specify.

    4. To avoid spurious precision, I push the text to be shown through string() with a specified format.

    5. You must ensure that the text label doesn't obscure data points.


    Code:
    sysuse auto, clear
    
    set scheme s1color 
    egen max_x = max(mpg), by(foreign)
    egen min_x = min(mpg), by(foreign) 
    bysort foreign (mpg) : gen pseudo_x = cond(_n == 1, min_x, cond(_n == _N, max_x, .))  
    
    egen mean = mean(price), by(foreign) 
    gen toshow = string(mean, "%4.0f") 
    
    twoway ///
    || line mean pseudo_x, sort  lc(gs8) lw(thin) || scatter mean  pseudo_x if pseudo_x == max_x, ms(none) mlabpos(11) mla(toshow) ///
    || scatter price mpg, ms(Oh) by(foreign, legend(off) note(means for each group)) xtitle("`: var label mpg'") ytitle("`: var label price'") name(G1, replace) 
    
    bysort foreign (mpg) : replace pseudo_x = cond(_n == 1, 10, cond(_n == _N, 45, .)) 
    
    twoway  ///
    || line mean pseudo_x, sort lc(gs8) lw(thin)  || scatter mean  pseudo_x if pseudo_x == 45, ms(none) mlabpos(11) mla(toshow) ///
    || scatter price mpg, ms(Oh) by(foreign, legend(off) note(means for each group)) xla(10(5)45) xtitle("`: var label mpg'") ytitle("`: var label price'") name(G2, replace)
    Click image for larger version

Name:	added_means_1.png
Views:	1
Size:	27.8 KB
ID:	1495635

    Click image for larger version

Name:	added_means_2.png
Views:	1
Size:	27.6 KB
ID:	1495636

    Comment


    • #3
      Thanks very much Nick!
      I also, after mucking around a bit, came to the conclusion that a new line might be needed, but still had no idea how to get the number to show and it certainly was nowhere near as elegant as your solution.
      Very much obliged, this is perfect, thank you!
      Cheers,
      Simon.

      Comment

      Working...
      X