Announcement

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

  • coefplot: subgraph-specific text box in plot area, in addition to subgraph header ?

    As many know (otherwise see here), with appropriate positioning, subtitles and notes can be used to place text inside the plot region of a graph.

    I need some creative help in figuring out if it is possible to apply this solution to coefplot (from ssc), used to present coefficients from sets of models organized by sub-graphs, in order to place text within the plot region of each sub-graph (a test statistic). Alas, the bylabel() sub-graph option (which cannot be repeated more than once per sub-graph) is busy for another reason, so it can't be used.

    The following code can be used to exemplify. Suppose I have sub-graph-specific stored text, and I want to add it to each sub-graph, let's say on the north-east corner of each area (not fitting very well in this example case).

    Code:
     sysuse auto, clear
    regress price mpg trunk length turn if foreign==0
    estimates store D
    regress price mpg trunk length turn if foreign==1
    estimates store F
    coefplot D, bylabel(Domestic Cars) || F, bylabel(Foreign Cars) ||, drop(_cons) xline(0)
    Any suggestion? I'm thinking of hijacking the legend function for this, but not entirely sure - and, as always, there might be a better solution I'm overlooking.
    I'm using StataNow/MP 18.5

  • #2
    coefplot is from SSC, as you are asked to explain (FAQ Advice #12). Since this is a twoway-type graph, you could use marker labels from a scatterplot within the -addplot()- option. However, an easier approach would be to use the Graph Editor, as it allows you to specify text for each subgraph and choose a single position to place the text more straightforwardly. Here is an approach based on your example:

    Code:
    sysuse auto, clear
    regress price mpg trunk length turn if foreign==0
    estimates store D
    regress price mpg trunk length turn if foreign==1
    estimates store F
    coefplot D, bylabel(Domestic Cars) || F, bylabel(Foreign Cars) ||, drop(_cons) xline(0)
    
    *PLACE TEXT CORRESPONDING TO SUBGRAPHS IN A LOCAL (SEQUENCE MATTERS)
    local text `" "{bf:Locally Manufactured}" "{bf:Imported}" "'
    local i 0
    foreach word of local text{
        local++i
        *(y x) COORDINATES HIGHLIGHTED
        gr_edit .plotregion1.plotregion1[`i'].AddTextBox added_text editor .7 -1000
        gr_edit .plotregion1.plotregion1[`i'].added_text[1].text.Arrpush "`word'"
    }
    Click image for larger version

Name:	Graph.png
Views:	1
Size:	41.5 KB
ID:	1775727

    Comment


    • #3
      Thanks Andrew,

      what I failed to mention (unlike ssc) is that I need a solution that does not require to pre-specifiy the y coordinate of whichever element can be used to include text in the plot area. Basically, I need to run loops, each producing multiple coefplots, many of them with slightly different y axis ranges, and leaving it up to Stata to determine the y axis range works really well this time. If there is no alternative I will work on this side of the problem, but I'd like to know if there's a way to solve this without specifying in advance the coordinates of the corner where I want to add the text. This issue, I suppose, affects not only the solution you show, but also the one you allude to.

      Here, someone proposes to add a global to the draw program of tickset_g.class Stata uses to fix axes range. I did it, but it returns the range of the x axis, not the y axis. As I plot vertical coefplots, the x axis is categorical and known, whereas it is the y axis that I need to know in order, for example, to add text on the north-west or north-east of the plot area.

      Any idea?

      [edit]

      In fact, given that the plotted results are pretty much definitive, the y ranges are unlikely to change, and I can simply plug in the numbers I know from having ran the code already - although the way I was attempting that differs from your solution and involves the addplot command (also from ssc). So the issue is a bit moot. But it remains interesting to know if it's possible to add text in a corner of unknown coordinates when the pos() and ring() options are not available - as it seems to be the case with coefplot, for reasons I don't quite understand.
      Last edited by Matteo Pinna Pintor; 10 Apr 2025, 15:29.
      I'm using StataNow/MP 18.5

      Comment


      • #4
        I don't know the inner workings of twoway graphs to retrieve the minimum value directly. However, below I can loop over the created sersets and obtain this value, which should correspond to the minimum of the lower CI. Then I can specify the position as min - 30 percent. I'm not sure how this specification will hold up across a range of graphs, but you can test it and modify accordingly. The y-coordinate does not change, but I can slightly expand the y-axis to allow for enough space for the label.

        Code:
        sysuse auto, clear
        estimates clear
        regress price mpg trunk length turn if foreign==0
        estimates store D
        regress price mpg trunk length turn if foreign==1
        estimates store F
        qui coefplot D, bylabel(Domestic Cars) || F, bylabel(Foreign Cars) ||, drop(_cons) xline(0)
        
        preserve
        local min 1e+56
        serset dir
        local N= `r(n_subgr)' -1
        forval i= 0/`=`N''{
            serset set `i'
            serset use, clear
            qui ds
            tokenize `r(varlist)'
            qui sum `1'
            local min= min(`min', `r(min)')
        }
        restore
        local x = floor(`min' + cond(`min'<0, .3*`min', -.3*`min'))
        
        coefplot D, bylabel(Domestic Cars) || F, bylabel(Foreign Cars) ||, drop(_cons) xline(0) xsc(r(`x' .)) ysc(r(.25 .))
        
        
        *PLACE TEXT CORRESPONDING TO SUBGRAPHS IN A LOCAL (SEQUENCE MATTERS)
        local text `" "{bf:Locally Manufactured}" "{bf:Imported}" "'
        local i 0
        foreach word of local text{
            local++i
            *(y x) COORDINATES HIGHLIGHTED
            gr_edit .plotregion1.plotregion1[`i'].AddTextBox added_text editor 0.5 `x'
            gr_edit .plotregion1.plotregion1[`i'].added_text[1].text.Arrpush "`word'"
        }
        Click image for larger version

Name:	Graph.png
Views:	1
Size:	43.1 KB
ID:	1775803

        Comment


        • #5
          Thanks a lot Andrew,

          I was reading about sersets, which were new to me, and indeed I was going in your direction by storing the highest CI but not quite sure what to do with it. Your post clarifies the final step! Alas, no time now to compare solutions - here's the result plugging in known y coordinates in text()

          Best
          Click image for larger version

Name:	result.JPG
Views:	2
Size:	57.1 KB
ID:	1775816

          Attached Files
          Last edited by Matteo Pinna Pintor; 11 Apr 2025, 14:00.
          I'm using StataNow/MP 18.5

          Comment

          Working...
          X