Announcement

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

  • Lines in a multiple kdensity graph

    Hi all,

    I would like to put a vertical line corresponding to the mean in the multiple graph panel generated by the following command:
    Code:
    twoway kdensity log_salesmnf, by(Year) xline
    I have already tried by generating :
    Code:
    gen logsales_mean=.
        forvalues c=2004/2015{
        quietly summarize log_sales if Year==`c'
        replace logsales_mean=r(mean) if Year==`c'
    }
    and making the graph with line(`logsales_mean') but it does not work...

    Thanks for the help!

  • #2
    Your code shows some confusion between line (a graph command) and xline(),a graph option. For what you want, I would not use either.

    Here is some technique. You don't give a data example, so I use a different dataset.

    Code:
    sysuse auto, clear
    set scheme s1color 
    egen mean = mean(mpg), by(foreign)
    twoway kdensity mpg, by(foreign)
    * observe in this case that extending spikes to 0.1 is a good idea 
    * your chosen limit may vary 
    * repeated values produce overplotting, even though they should be identical 
    bysort foreign : gen show = cond(_n == 1, 0.1, .) 
    twoway spike show mean || kdensity mpg, ///
    by(foreign, legend(off) note(spikes show means)) ytitle(Density) xtitle("`: var label mpg'")
    Click image for larger version

Name:	density_and_spike.png
Views:	1
Size:	26.9 KB
ID:	1468995

    Comment


    • #3
      First of all many thanks for the reply!
      It does the job, but I really do not understand why it is necessary to generate the variable "show". Is it something like it allows to create a variable mean having all identical values and to take just one value?

      Thanks Professor!

      Comment


      • #4
        Perhaps it's not necessary. I welcome your alternative way of doing it.

        Comment


        • #5
          I am trying to but not finding a more efficient way. I will let you know.
          For the moment many thanks again!

          Comment


          • #6
            If you had just one panel, then xli() would work as would a call to scatteri. But you have several panels. The means vary, so they must go in a variable. It may seem overkill but I very much doubt that there's another way. (Creating graphs separately and using graph combine is too ugly even to contemplate.)

            Comment


            • #7
              Yes I agree.
              And may I ask a related question? What if I would like to add a different note in each of the plots? Is there a way? (for instance I would like to insert the mean in levels near the vertical line representing the mean in logs for each plot)
              Last edited by Federico Nutarelli; 06 Nov 2018, 02:18.

              Comment


              • #8
                Use a marker label variable.

                Comment


                • #9
                  I will try. I do not know yet what it is but I will do my best.
                  Thanks for the help!

                  Comment


                  • #10
                    Something like this?
                    Code:
                    twoway spike show mean || kdensity log_salesmnf, ///
                    by(Year, legend(off)) ytitle(Density) || scatter show mean, mlabel(means)
                    where means is the variable containing the means in level created with
                    Code:
                    egen means = mean(salesmnf), by(Year)
                    Last edited by Federico Nutarelli; 06 Nov 2018, 02:48.

                    Comment


                    • #11
                      I can't see what that does or even if it's legal. (No data example from you yet; no graph shown.)

                      Here is some more technique.

                      Code:
                      sysuse auto, clear
                      set scheme s1color 
                      egen mean = mean(mpg), by(foreign)
                      gen text = string(mean, "%3.1f") 
                      * twoway kdensity mpg, by(foreign)
                      * observe in this case that extending spikes to 0.1 is a good idea 
                      * your chosen limit may vary 
                      * repeated values produce overplotting, even though they should be identical 
                      bysort foreign : gen show = cond(_n == 1, 0.1, .) 
                      
                      twoway spike show mean, lcolor(blue) || ///
                      scatter show mean, ysc(r(. 0.105)) ms(none) mla(text) mlabpos(12) mlabc(blue) mlabsize(medium) || ///
                      kdensity mpg, by(foreign, legend(off) note(spikes show means)) ytitle(Density) xtitle("`: var label mpg'")
                      Click image for larger version

Name:	densities_spikes.png
Views:	1
Size:	29.1 KB
ID:	1469106

                      Comment


                      • #12
                        Ok. It does the job. I obtain a similar graph but with a scatter point on the top.

                        Thanks a lot!

                        Comment


                        • #13
                          Originally posted by Nick Cox View Post
                          I can't see what that does or even if it's legal. (No data example from you yet; no graph shown.)

                          Here is some more technique.

                          Code:
                          sysuse auto, clear
                          set scheme s1color
                          egen mean = mean(mpg), by(foreign)
                          gen text = string(mean, "%3.1f")
                          * twoway kdensity mpg, by(foreign)
                          * observe in this case that extending spikes to 0.1 is a good idea
                          * your chosen limit may vary
                          * repeated values produce overplotting, even though they should be identical
                          bysort foreign : gen show = cond(_n == 1, 0.1, .)
                          
                          twoway spike show mean, lcolor(blue) || ///
                          scatter show mean, ysc(r(. 0.105)) ms(none) mla(text) mlabpos(12) mlabc(blue) mlabsize(medium) || ///
                          kdensity mpg, by(foreign, legend(off) note(spikes show means)) ytitle(Density) xtitle("`: var label mpg'")
                          [ATTACH=CONFIG]n1469106[/ATTACH]
                          Thanks for sharing the code. It works really well.
                          I have a additional question. How can I add weights when I drawing the graph (If I want to add [aw=weights variable])?

                          Thanks for your help!

                          Comment


                          • #14
                            Well, you are going to need add weights to your commands. For getting weighted means in a variable, I tend just to calculate the numerator and denominator separately and divide. There are community-contributed commands for that too.

                            Comment

                            Working...
                            X