Announcement

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

  • Adding short line segments to Stata graphs

    Stata's twoway command has xline and yline options, but they go all the way across the graph. Is there a convenient way to draw shorter line segments? For example, how would you add little arrows showing how much area is in a certain range under a normal curve.
    Attached Files

  • #2
    Code:
    help twoway pci
    help twoway pcarrowi

    Comment


    • #3
      Thanks! What about bidirectional arrows? I see a pcbarrow command that draws bidirectional arrows from data in memory, but no pcbarrowi command to draw bidirectional arrows from coordinates on the command line.

      Comment


      • #4
        I would just superimpose two arrows with the same colour.

        Alternatively, some technique.

        Code:
        sysuse auto, clear
        summarize weight price, detail 
        
        gen x1 = 1760 in 1
        gen x2 = 3190 in 1
        gen x3 = 4840 in 1
        gen y = 2500 in 1
        
        scatter price weight || pcbarrow y x1 y x2 in 1 || pcbarrow y x2 y x3 in 1 , legend(off) ytitle("`: var label price'") xtitle("`: var label weight'")
        Last edited by Nick Cox; 15 Nov 2023, 10:53.

        Comment


        • #5
          I did notice the interest in two-headed arrows and was thinking first that the two superimposed arrows recommended in #2 and #4 could be two arrows pointing in different directions.

          This silly example shows the idea.

          Code:
          sysuse auto, clear
          scatter price weight || pcarrowi 2000 500 5000 500, lcolor(stc1) mcolor(stc1) || pcarrowi 5000 500 2000 500, lcolor(stc1) mcolor(stc1)
          I suspect that my second idea of just creating variables for the purpose may work a little better.

          (#3 and #4 "crossed in the post" -- English idiom, may not be idiomatic in American.)

          Comment


          • #6
            Thanks for your tips! I made double-headed arrows by overlaying single-headed arrows in opposite directions.
            Here's the final result, which looks better than the non-Stata plot I posted originally:
            Code:
            twoway ///
                   (func y=100*normalden(x), range(-3 3) lw(vthick) lcolor(navy)) ///
                   (pcarrowi 0 -1 0 +1, lcolor(gray) mcolor(gray)) (pcarrowi 0 +1 0 -1, lcolor(gray) mcolor(gray))  ///
                   (pcarrowi 10 -0.5 10 +0.5, lcolor(gray) mcolor(gray)) (pcarrowi 10 +0.5 10 -0.5, lcolor(gray) mcolor(gray))  ///
             , xlab(-3(.2)3, grid angle(90)) ylab(0(10)40, grid) legend(off) ///
               ytitle("Density", size(large)) xtitle("Standard deviations from the mean" "(Z)", size(large)) ///
               title("The standard normal probability density") ///
               text(2 0 "68%") text(12 0 "38%")
            Click image for larger version

Name:	normal pdf.JPG
Views:	1
Size:	111.3 KB
ID:	1734148

            Last edited by paulvonhippel; 16 Nov 2023, 15:53.

            Comment


            • #7
              Bonus question: Why is the X axis label so far from the X axis? Can I move it closer without manual touch-up?

              Comment


              • #8
                Code:
                help axis scale options
                and look for titlegap()

                Comment


                • #9
                  Strangely this has no effect. The following code produces an identical looking graph regardless of the value of -titlegap()-:
                  Code:
                  twoway ///
                         (scatteri 20 -.8 20 .8 80 .8 80 -.8, recast(area) color(gray*0.3) ) ///
                         (func y=100*normal(x), range(-3 3) lw(vthick) lcolor(navy)) ///
                         (func y=100*(1/2+.37*x), range(-.8 .8) lw(medthick) lpattern(dash) lcolor(yellow)) ///
                   , xlab(-3(.2)3, grid angle(90)) ylab(0(10)100, grid) legend(off) ///
                     xscale(titlegap(0)) ///
                     ytitle("Percentile (P)", size(large)) xtitle("Standard deviations from the mean" "(Z)", size(large)) ///
                     title("The cumulative standard normal distribution") ///
                     subtitle("is approximately linear, with slope 37, between the 21st and 81st percentile")

                  Comment


                  • #10
                    -recast- may be helpful. For example
                    Code:
                    loc yval1=2
                    loc yval2=2
                    loc xval1=5
                    loc xval2=10
                    twoway pcarrowi `yval1' `xval1' `yval2' `xval2', recast(pcbarrow)

                    Comment

                    Working...
                    X