user319487
user319487

Reputation:

How can I align the y-axes of combined graphs?

I am trying to combine multiple graphs in Stata using the command graph combine. The individual graphs are produced from the community-contributed command ciplot.

Below is a reproducible example:

sysuse auto 
ciplot foreign, by(rep78) hor ///
    graphregion(color(white)) ///
    rcap(lcolor(black) msiz(zero)) ///
    mc(black) ms(O) ///
    note("") xtitle( ) ///
    fysize(62.5) saving(g1, replace ) nodraw

ciplot foreign, by(headroom) hor ///
    graphregion(color(white)) ///
    rcap(lcolor(black) msiz(zero)) ///
    mc(black) ms(O) ///
    note("") xtitle( ) ///
    fysize(100) saving(g2, replace ) nodraw

gr combine g1.gph ///
    g2.gph ///
    , col(1) xcom graphregion(color(white)) ///
    title("Proportion of patients across studied variables")

All works as expected and I get a graph like the one below:

enter image description here

The problem is that the y-axes of the graphs start in slightly different positions, due to the different width of the labels of individual ticks. The problem gets even worse when larger discrepancies between these labels exist.

Is there a way to force the y-axes to start from the same point in the graph region?

Upvotes: 1

Views: 3923

Answers (2)

user8682794
user8682794

Reputation:

A tick's label width in this case clearly depends on the number of decimals.

There are two main problems here:

  • ciplot does not allow the format of variable levels to be specified in the y-axis label.
  • graph combine draws again both graphs before it combines them.

Below is a a fairly general fix that standardises the decimals in the combined graph:

graph combine g1 g2, cols(1) ///
                     xcommon ///
                     graphregion(color(white)) ///
                     title("Proportion of patients across studied variables") ///
                     nodraw ///
                     name(g3, replace)

local decimals 1
local i 0

foreach var in rep78 headroom {
    local ++i
    local j 0
    quietly levelsof `var', local(`var'm)
    foreach l of local `var'm {
        local ++j
        local il : display %2.`decimals'f `l'
        .g3.plotregion1.graph`i'.yaxis1.major.ticks[`j'][2] = "`il'"
    }  
}

graph display g3

enter image description here

Note that you cannot use the ylabel() option in ciplot to specify the tick labels because you do not know a priori the actual tick values.

Upvotes: 0

Roberto Ferrer
Roberto Ferrer

Reputation: 11102

One way to improve the graph is using the titlegap() option. But it may not be satisfactory because manual tweaking is involved, and the result won't be perfect. Furthermore, if many graphs are being made, incorporating the change into the code might turn out to be cumbersome.

For example:

sysuse auto, clear

ciplot foreign, by(rep78) hor ///
    graphregion(color(white)) ///
    rcap(lcolor(black) msiz(zero)) ///
    mc(black) ms(O) ///
    note("") xtitle( ) ///
    yscale(titlegap(3.5)) ///
    fysize(62.5) saving(g1, replace ) nodraw

ciplot foreign, by(headroom) hor ///
    graphregion(color(white)) ///
    rcap(lcolor(black) msiz(zero)) ///
    mc(black) ms(O) ///
    note("") xtitle( ) ///
    fysize(100) saving(g2, replace ) nodraw

gr combine g1.gph g2.gph, ///
    col(1) xcom graphregion(color(white)) ///
    title("Proportion of patients across studied variables")

The outergap() option provides a similar solution. These options are documented in help axis_scale_options.

Upvotes: 3

Related Questions