u17
u17

Reputation: 2824

Directlabels outside plotting area / Disable directlabels' auto-resize

Package 'directlabels' apparently by default tries to fit each label inside the normal plotting area by reducing label font size.

Below, Label for One, Label for Two and Label for Threeeeeeeeee should all have the same font size and it is ok if the labels run out of the plotting area (since clip is disabled for custom annotations to show).

In fact, I might want to set xlim=c(1,3) and the labels should be entirely outside the plotting area. The left column of images below is for xlim=c(1,3.4), the right colum for xlim=c(1,3).

I learned that cex can be used to reset a label's fontsize, but it seems to conflict with the package's label separation algorithm. The top row of images below is for no cex, the bottom row for cex=1.

It would be great to find a way to have labels don't overlap, be the same font size, and that works with xlim=c(1,3) and xlim=c(1,3.4).

enter image description here

library(reshape)
library(ggplot2)
library(directlabels)

df=data.frame(
  x = 1:3,
  One=c(12, 8, 13),
  Two=c(13, 7, 11),
  Threeeeeeeeee=c(11, 9, 11))

df.d.melt = melt(df[,c("x","One","Two","Threeeeeeeeee")], id.vars="x")
df.d.melt$variable1 = df.d.melt$variable
levels(df.d.melt$variable1) = paste("","Lable for",levels(df.d.melt$variable1))

p = ggplot(df.d.melt, aes(x=x, y=value, color=variable)) + 
  geom_line(size=1.1) +
  geom_text(aes(x =3.4, y=8, label="Custom Outside\nChart Annotation"), show_guide=FALSE) + 
  coord_cartesian(xlim=c(1,3.4)) +
  geom_dl(aes(label=variable1), method=list("last.qp", cex=1), show_guide=FALSE) + 
  theme(legend.position="top",plot.margin = unit(c(0, 4, 0, 0), "cm")) 

p1 <- ggplot_gtable(ggplot_build(p))
p1$layout$clip[p1$layout$name=="panel"] <- "off"
grid.draw(p1)

Upvotes: 2

Views: 1171

Answers (2)

Toby Dylan Hocking
Toby Dylan Hocking

Reputation: 116

By default, directlabels assumes you want to have readable labels INSIDE the plotting region, so it reduces the text size so the label fits inside using reduce.cex.lr. Labels outside the plot can be accomplished by defining a custom Positioning Method that does not reduce the text size, e.g.

do.not.reduce <-
  list(cex=2, "last.points", "calc.boxes",
       qp.labels("y", "bottom", "top", make.tiebreaker("x", "y")))

WithLegend <- ggplot(df.d.melt, aes(x=x, y=value, color=variable)) + 
  geom_line(size=1.1) +
  geom_text(aes(x =3.4, y=8, label="Custom Outside\nChart Annotation")) + 
  coord_cartesian(xlim=c(1,3)) +
  theme(plot.margin = unit(c(0, 4, 0, 0), "cm"))
WithLabels <- direct.label(WithLegend, "do.not.reduce")
GTable <- ggplot_gtable(ggplot_build(WithLabels))
GTable$layout$clip[GTable$layout$name=="panel"] <- "off"
grid.draw(GTable)

Upvotes: 1

u17
u17

Reputation: 2824

A working solution is to attach the labels to additional invisible short lines lines at the left side of the chart (e.g. defined over x=1 to x=1.001) and use directlabels' trans_new to move the annotations to the desired x-value.

Upvotes: 0

Related Questions