Announcement

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

  • Plotting two or more overlapping density curves on the same graph.

    Good Afternoon,

    I am using the command "histogram score, frequency normal" to plot a continuous variable with frequencies and with an overlaid normal density curve.

    Is there a way to plot multiple density curves onto one graph (with each line in a different colour and a legend on the side)?

    Thank you,

    Kerry

  • #2
    Hello Kerry. If you're trying to make overlapping frequency polygons, you may find some useful info in this thread: HTH.
    --
    Bruce Weaver
    Email: [email protected]
    Version: Stata/MP 18.5 (Windows)

    Comment


    • #3
      Hi there,

      Thank you, I read through that post. I'm still unsure how to achieve this with multiple normal density curves.

      Kerry

      Comment


      • #4
        If you're overlaying histograms and normal densities then usually one reaches for twoway histogram but that doesn't allow a normal option.

        This script is an awkward mix of particular and general code but may signal ways to generalise the method.

        Code:
        sysuse auto, clear
        set scheme s1color 
        
        * choose start and width etc. by looking at results 
        su length 
        local start = 140
        local bin = 10 
        local opts start(`start') width(`bin') 
        
        local normal_begin = 130 
        local normal_end = 250 
        local range ra(`normal_begin' `normal_end') 
        
        local colors red blue black 
        
        local call 
        
        levelsof foreign 
        tokenize "`r(levels)'" 
        local nlevels : word count `r(levels)' 
        
        forval j = 1/`nlevels' { 
            su length if foreign == ``j'' 
            scalar mu`j' = r(mean)
            scalar sd`j' = r(sd)
        
            local color : word `j' of `colors' 
            local call `call' || histogram length if foreign == ``j'', bcolor(`color'%20) `opts' 
            local call `call' || function normalden(x, mu`j', sd`j') , `range' lcolor(`color') 
        } 
        
        twoway `call'  xla(`normal_begin'(10)`normal_end') ///
        legend(order(3 "Foreign" 1 "Domestic") pos(12))  ytitle(Density) xtitle(Length (inches)) /
        
        
        qplot length, over(foreign) trscale(invnormal(@)) xtitle(standard normal) ///
        ytitle(Length (inches)) legend(ring(0) pos(11) col(1)) yla(, ang(h))
        Click image for larger version

Name:	overlay1.png
Views:	1
Size:	36.4 KB
ID:	1417049


        I have a great deal of gratuitous advice.

        1. Overlapping histograms usually work badly unless you use transparency (as here, requires Stata 15 or later) or remove fill colour.

        2. Overlapping histograms can be complicated enough with say 2 groups: 5 or 10 is usually a disaster. It's reasonable that nearly similar distributions overlap mightly, but the graph is still likely to seem a mess.

        3. Using frequency scale is possible, but requires more work than above.

        4. Histograms need choices on start and bin width, even if you follow the default, and are sensitive to such choices.

        5. Consistent colours to match histograms and normal curves are a really important detail.


        The script includes a way to get superimposed normal quantile plots. Note that qnorm (the official command) is a dead end for this, but you can make progress with qplot which must be installed first from the Stata Journal website.

        Click image for larger version

Name:	overlay2.png
Views:	1
Size:	26.0 KB
ID:	1417050


        What I like about these plots:

        6. On quantile plots you get to see the data in full detail, without any need for arbitrary decisions on binning. With small samples it becomes especially obvious that there are only a few data points and especial need for caution.

        7. On quantile plots level is indicated by the vertical position of each series and spread by the slope.

        8. On normal quantile plots how well normals fit is indicated by how closely each series plots to a straight line. You get to see where the fit is best and worst.

        9. I assert that these plots don't become visually complicated as quickly as overlapping histograms as the number of groups increases.

        Comment


        • #5
          Is there a way to plot multiple density curves onto one graph (with each line in a different colour and a legend on the side)?
          When I first read the query, I got the impression you needed a histogram for a single variable, with density (instead of frequency), adding, say, two different curves (normal density and kernel density) in different colors (I also added "styles" by myself) and an add text "on the side".

          Maybe I got it wrong but, if not, that is the graph I imagined for you:

          Code:
          sysuse auto
          histogram mpg, frequency fcolor(cranberry) normal normopts(lcolor(blue) lpattern(longdash)) kdensity kdenopts(lcolor(yellow)) text(15 13 "Kernel" 18 25 "Normal")
          Click image for larger version

Name:	Graph_hist1.png
Views:	1
Size:	35.7 KB
ID:	1417060



          Shall you wish density in the Y axis, you may type:

          Code:
          histogram mpg, density fcolor(cranberry) normal normopts(lcolor(blue) lpattern(longdash)) kdensity kdenopts(lcolor(yellow)) text(0.06 13 "Kernel" 0.06 25 "Normal")
          Hopefully that helps.
          Last edited by Marcos Almeida; 04 Nov 2017, 06:30.
          Best regards,

          Marcos

          Comment


          • #6
            Hi all,

            I'm afraid I find myself in the same boat as Kerry, and have been trying the following code to generate something similar to what Nick has advised above, however I'd like the y axis to display percentages:

            tw hist atar0 [fw=wt2009XX], fc(none) lc(black) percent by(,addplot(function 100*10*(normalden(x,66,18),ra(2.5,99.9)) || hist atar1 [fw=wt2009XX], fc(none) lp(dash) lc(red) percent by(,addplot(function 100*10*(normalden(x,81,13),ra(30,99.95))

            the error i'm getting is:

            parentheses do not balance
            r(198);

            Grateful for any advice at all, and pre-emptive apologies if this is not sufficiently clear.

            Esha

            Comment


            • #7
              There is no data example here in #6 to check anything.

              by() needs a varname as first argument.

              addplot() isn't a suboption of by()

              My main advice in #4 was not to do this...

              Comment


              • #8

                Hello Statalist experts,

                I'm trying to plot 2 densities in one plot: as follows:

                the code is :

                Code:
                skewtreg ex_pi core reer_gap gdp_gap gsci pi_lte if shift ==1,difficult
                predict resid1, residuals
                predict fitted1 if e(sample)
                kdensity resid1, normal
                kdensity fitted1, kernel( gaussian) gen(x1  gaussian1)
                
                
                skewtreg ex_pi core reer_gap gdp_gap gsci pi_lte if shift ==0, difficult
                predict resid0, residuals
                predict fitted0 if e(sample)
                kdensity resid0, normal
                kdensity fitted0, kernel( gaussian) gen(x0  gaussian0)
                
                 
                 //entire sample
                 skewtreg ex_pi core reer_gap gdp_gap gsci pi_lte, difficult
                predict resid2, residuals
                predict fitted2 if e(sample)
                kdensity resid2, normal
                kdensity fitted2, kernel(gaussian) gen(x2  gaussian2)
                
                
                twoway (line (x0 gaussian0),  lcolor(grey))  (line (x1 gaussian1),  lcolor(cranberry)), legend(order(1 "Core-2Q, before 2006q3" 2 "Core-2Q, after 2006q3"))
                the plot appears rotated, like this :
                Click image for larger version

Name:	Capture1.PNG
Views:	2
Size:	81.7 KB
ID:	1683094

                Can Anyone fix it for me,

                Thanks in advance
                Last edited by Sarah Hussein; 23 Sep 2022, 09:34.

                Comment

                Working...
                X