Search code examples
rplotlegendsubscript

How to shift one specific legend label with subscript slightly downwards?


I've generated a subscript in a legend label with expression() that shifts the entire label slightly upward and looks lousy (the red one in the middle).

plot(1:10, type="l")
curve(x^2, col=2, add=TRUE)
curve(x^3, col=3, add=TRUE)
legend("bottomright", lty=1, col=3:1,
       legend=c(expression(z>2),
                expression(z==italic(z[1])), 
                expression(z==0)))

enter image description here

With help of this great solution I get what I want by multiplying the y-location of the specific label, figuring out the right number of spaces of the legend text, and shifting the x-values, by values that I've laboriously diced.

a <- legend("bottomright", lty=1, col=3:1, trace=T, 
            legend=rep("         ", 3))
a$text$y[2] <-  a$text$y[2]/1.043
text(a$text$x-.3, a$text$y, c(expression(z>2),
                              expression(z==italic(z[1])), 
                              expression(z==0)), pos=4)

However, it could become quite a hobby to figure out the right values, and it might not be reliable when sending the plot to a device (e.g. pdf), because plot outputs, e.g. by pdf are dynamic (consider various layouts or pdf sizes).

The cause is indeed the expression(), since

mean(a$text$y[-2]) == a$text$y[2]
# [1] TRUE

I didn't find an option such as legend.txt.y=c(1, 1.043, 1), and the x and y seem to only accept scalars. And the question is still open how much exactly a subscripted label is shifted.

Might there be option I've overlooked or any solution to shift the expression() slightly downwards by a factor or something?


Solution

  • Assuming the ultimate goal is just to have legend entries evenly spaced you could consider using phantom() on each element in the legend so that an equal amount of space is reserved but nothing is drawn. This sidesteps the need to calculate the adjustment although it does create a small amount of whitespace on the right side of the legend. In this case each element is having 'i1' invisibly appended (as you don't seem to be able to generate subscripts in plotmath without it being next to something).

    plot(1:10, type="l")
    curve(x^2, col=2, add=TRUE)
    curve(x^3, col=3, add=TRUE)
    legend("bottomright", lty=1, col=3:1,
           legend=c(expression(z>2*phantom(i[1]),
                               z==italic(z[1])*phantom(i[1]),
                               z==0*phantom(i[1]))))