I have generated a simple plot in R (version R version 3.0.1 (2013-05-16)) using ggplot2
(version 0.9.3.1) that shows the correlation coefficients for a set of data. Currently, the legend colorbar on the right side of the plot is a fraction of the entire plot size.
I would like the legend colorbar to be same height as the plot. I thought that I could use the legend.key.height
to do this, but I have found that is not the case. I investigated the grid
package unit
function and found that there were some normalized units in there but when I tried them (unit(1, "npc")
), the colorbar was way too tall and went off the page.
How can I make the legend the same height as the plot itself?
A full self contained example is below:
# Load the needed libraries
library(ggplot2)
library(grid)
library(scales)
library(reshape2)
# Generate a collection of sample data
variables = c("Var1", "Var2", "Var3")
data = matrix(runif(9, -1, 1), 3, 3)
diag(data) = 1
colnames(data) = variables
rownames(data) = variables
# Generate the plot
corrs = data
ggplot(melt(corrs), aes(x = Var1, y = Var2, fill = value)) +
geom_tile() +
geom_text(parse = TRUE, aes(label = sprintf("%.2f", value)), size = 3, color = "white") +
theme_bw() +
theme(panel.border = element_blank(),
axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1),
aspect.ratio = 1,
legend.position = "right",
legend.key.height = unit(1, "inch")) +
labs(x = "", y = "", fill = "", title = "Correlation Coefficients") +
scale_fill_gradient2(limits = c(-1, 1), expand = c(0, 0),
low = muted("red"),
mid = "black",
high = muted("blue"))
To specify the legend box size you could use + theme(legend. key. size = unit(2, "cm")) .
To change the legend size of the plot, the user needs to use the cex argument of the legend function and specify its value with the user requirement, the values of cex greater than 1 will increase the legend size in the plot and the value of cex less than 1 will decrease the size of the legend in the plot.
You can use the following syntax to change the legend labels in ggplot2: p + scale_fill_discrete(labels=c('label1', 'label2', 'label3', ...)) The following example shows how to use this syntax in practice.
It seems quite tricky, the closest I got was this,
## panel height is 1null, so we work it out by subtracting the other heights from 1npc
## and 1line for the default plot margins
panel_height = unit(1,"npc") - sum(ggplotGrob(plot)[["heights"]][-3]) - unit(1,"line")
plot + guides(fill= guide_colorbar(barheight=panel_height))
unfortunately the vertical justification is a bit off.
Edit Updating to ggplot v3.0.0
This is messy, but based on this answer, and delving deeper into the ggplot grob, the legend can be positioned precisely.
# Load the needed libraries
library(ggplot2)
library(gtable) #
library(grid)
library(scales)
library(reshape2)
# Generate a collection of sample data
variables = c("Var1", "Var2", "Var3")
data = matrix(runif(9, -1, 1), 3, 3)
diag(data) = 1
colnames(data) = variables
rownames(data) = variables
# Generate the plot
corrs = data
plot = ggplot(melt(corrs), aes(x = Var1, y = Var2, fill = value)) +
geom_tile() +
theme_bw() +
theme(panel.border = element_blank()) +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) +
theme(aspect.ratio = 1) +
# theme(legend.position = "right", legend.key.height = unit(1, "inch")) +
labs(x = "", y = "", fill = "", title = "Correlation Coefficients") +
scale_fill_gradient2(limits = c(-1, 1), breaks = c(-1, -.5, 0, .5, 1), expand = c(0,0),
low = muted("red"), mid = "black", high = muted("blue")) + # Modified line
geom_text(parse = TRUE, aes(label = sprintf("%.2f", value)), size = 3, color = "white") +
scale_x_discrete(expand = c(0,0)) + # New line
scale_y_discrete(expand = c(0,0)) # New line
plot
# Get the ggplot grob
gt = ggplotGrob(plot)
# Get the legend
leg = gtable_filter(gt, "guide-box")
# Raster height
leg[[1]][[1]][[1]][[1]][[1]][[2]]$height = unit(1, "npc")
# Positions for labels and tick marks - five breaks, therefore, five positions
pos = unit.c(unit(0.01,"npc"), unit(.25, "npc"), unit(.5, "npc"), unit(.75, "npc"), unit(.99, "npc"))
# Positions the labels
leg[[1]][[1]][[1]][[1]][[1]][[3]]$children[[1]]$y = pos
# Positions the tick marks
leg[[1]][[1]][[1]][[1]][[1]][[5]]$y0 = pos
leg[[1]][[1]][[1]][[1]][[1]][[5]]$y1 = pos
# Legend key height ?
leg[[1]][[1]][[1]][[1]]$heights = unit.c(rep(unit(0, "mm"), 3),
unit(1, "npc"),
unit(0, "mm"))
# Legend height
leg[[1]][[1]]$heights[[3]] = sum(rep(unit(0, "mm"), 3),
unit(1, "npc"),
unit(0, "mm"))
# grid.draw(leg) # Check on heights and y values
# gtable_show_layout(gt) # Manually locate position of legend in layout
gt.new = gtable_add_grob(gt, leg, t = 7, l = 9)
# Draw it
grid.newpage()
grid.draw(gt.new)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With