2

I'm trying to implement one of the answers in this question

I'm using the third answer, the one with the function new_legend. Here's my output. enter image description here

I cannot share the data. Just think of it as columns in data.frames: df1, df2, df12.

The code that produces the image is the following:

    add_legend <- function(...) {
      opar <- par(fig=c(0, 1, 0, 1), oma=c(0, 0, 0, 0), 
                  mar=c(0, 0, 0, 0), new=TRUE)
      on.exit(par(opar))
      plot(0, 0, type='n', bty='n', xaxt='n', yaxt='n')
      legend(...)
    }

op <- par(cex = 1)
#bc
plot(df1[,2],df2[,1],xlab="save",ylab="log85",ylim=c(6, 10))
#bc2
points(df1[,2],df2[,3],xlab="save",ylab="log85",col=2)
#od
points(df1[,2],df1[,1],pch=3,col=3)
#od2
points(df12[,2],df12[,1],pch=3)
add_legend("top", legend=c("too big text", "description with","a lot of" ,"useless freespace"),
           col=c(1, 2,3,1),pch=c(1,1,3,3),horiz=TRUE, bty='n', x.intersp = 0.3)

I would like to put the legend with less free space between descriptions and with a bigger font size. I've tried using x.intersp but it just diminishes the distance between the symbol and its description, and not the distance between a previous description and the next symbol. If I use par(cex=1) before doing the plot, then the font size is good, but more text is clipped.

Any help would be appreciated.

Community
  • 1
  • 1
An old man in the sea.
  • 1,169
  • 1
  • 13
  • 30

1 Answers1

1

You can't do this in the current R version (3.5.0).

If you specify horiz=TRUE or nc>1, then the horizontal distance between each legend entry will always be equal and the space between each item will be determined by the longest item. This is important aesthetically if the number of items spans across multiple columns and rows, but not so important when there are multiple columns and only one row as seen in your example. The result can, as you subtly suggest, become rather ugly and appear to waste space if the lengths of the items are not equal. Unfortunately, there doesn't appear to be an argument to manually control the distance between each item. So you've hit one of the limitations of R. One workaround is to hack the legend function yourself and find what part of the code places the legend entries. I once hacked it to allow you to adjust the size of the filled boxes relative to the other parts of the legend. I've noticed that the number of arguments to the legend function has been growing with each new major R upgrade, for example, the seg.len argument is a fairly recent addition to allow the line lengths to be adjusted. Perhaps in a future version, there will be a new argument that allows you to manually specify the horizontal spacing between legend entries (and adjust the size of the filled boxes). :)

Maybe your best option here is to specify nc=2 instead of horiz=TRUE.

Edit: The text.width argument may also help if there is too much space between each legend entry, but again, the distance between each item must be equal.

Edward
  • 48
  • 5