vertical alignment of gridExtra tableGrob (R grid graphics/grob)
try this,
library(gridExtra)
justify <- function(x, hjust="center", vjust="center", draw=TRUE){
w <- sum(x$widths)
h <- sum(x$heights)
xj <- switch(hjust,
center = 0.5,
left = 0.5*w,
right=unit(1,"npc") - 0.5*w)
yj <- switch(vjust,
center = 0.5,
bottom = 0.5*h,
top=unit(1,"npc") - 0.5*h)
x$vp <- viewport(x=xj, y=yj)
if(draw) grid.draw(x)
return(x)
}
g <- tableGrob(iris[1:3,1:2])
grid.newpage()
justify(g,"right", "top")
Center align bottom legend viewport or grob relative to plot area with grid package
I don't understand why you're doing so much with individual viewports. It makes it very complex. I would have thought it was much easier to have one viewport for the legend and then control the x coordinate of the text and circles relative to that. Something like this; I'm not sure it's exactly what you want but it feels it should be easy to control if you need to tweak it:
library(grid)
draw <- function() {
masterLayout <- grid.layout(
nrow = 4,
ncol = 1,
heights = unit(c(0.1, 0.7, 0.1, 0.1), rep("null", 4)))
vp1 <- viewport(layout.pos.row=1, layout.pos.col = 1, name="title")
vp2 <- viewport(layout.pos.row=2, layout.pos.col = 1, name="plot")
vp3 <- viewport(layout.pos.row=3, layout.pos.col = 1, name="legend")
vp4 <- viewport(layout.pos.row=4, layout.pos.col = 1, name="caption")
pushViewport(
vpTree(viewport(layout = masterLayout, name = "master"),
vpList(vp1, vp2, vp3, vp4)))
## Draw main plot
seekViewport("plot")
pushViewport(viewport(width=unit(.8, "npc")))
grid.rect(gp=gpar("fill"="red")) # dummy chart
popViewport(2)
## Draw legend
seekViewport("legend")
colors <- list(first="red", second="green", third="blue")
lab_centers <- seq(from = 0.2, to = 0.8, length = length(colors))
disp <- 0.03 # how far to left of centre circle is, and to right text is, in each label
for(i in 1:length(colors)){
grid.circle(x = lab_centers[i] - disp, r = 0.1, gp=gpar(fill = colors[[i]], col=NA))
grid.text("text", x = lab_centers[i] + disp)
}
popViewport(2)
}
draw()
grid.lines(c(0.5, 0.5), c(0, 1))
If your legend labels aren't all the same length, you probably need to left align them and tweak the way I've used a disp parameter but shouldn't be too hard.
How can I top align these tables in gtable using grid.arrange?
I've located an answer from this prior SO post. It appears to me that the padding of the output of the two shorter tables gtable_combine(...)
differs from the output of the longer table as the top padding is by default a function of the length of the table, and here the two tables, even when combined, will differ in length. The function @baptiste outlines in his answer solves this problem by fixing that padding value. Implementing it in my use case looks like this:
justify <- function(x, hjust="center", vjust="top", draw=FALSE){
w <- sum(x$widths)
h <- sum(x$heights)
xj <- switch(
hjust,
center = 0.5,
left = 0.5 * w,
right = unit(1, "npc") - 0.5 * w
)
yj <- switch(
vjust,
center = 0.5,
bottom = 0.5 * h,
top = unit(1, "npc") - 0.5 * h
)
x$vp <- viewport(x=xj, y=yj)
if(draw) grid.draw(x)
return(x)
}
grid.arrange(
justify(
gtable_combine(
gtable_add_grob(
tableGrob(mtcars[1:3, 1:2], rows = NULL),
grobs = segmentsGrob(y1 = unit(0, "npc"),
gp = gpar(fill = NA, lwd = 2)),
t = 1,
l = 1,
r = ncol(mtcars[1:3, 1:2])
),
gtable_add_grob(
tableGrob(mtcars[1:3, 1:2], rows = NULL),
grobs = segmentsGrob(y1 = unit(0, "npc"),
gp = gpar(fill = NA, lwd = 2)),
t = 1,
l = 1,
r = ncol(mtcars[1:3, 1:2])
),
along = 2
)
),
justify(
gtable_add_grob(
tableGrob(mtcars[1:8, 1:2], rows = NULL),
grobs = segmentsGrob(y1 = unit(0, "npc"),
gp = gpar(fill = NA, lwd = 2)),
t = 1,
l = 1,
r = ncol(mtcars[1:3, 1:2])
)
),
ncol = 2
)
Specify position of geom_text by keywords like top, bottom, left, right, center
geom_text
wants to plot labels based on your data set. It sounds like you're looking to add a single piece of text to your plot, in which case, annotate
is the better option. To force the label to appear in the same position regardless of the units in the plot, you can take advantage of Inf
values:
sp <- ggplot(mpg, aes(hwy, cty, label = "sometext"))+
geom_point() +
annotate(geom = 'text', label = 'sometext', x = -Inf, y = Inf, hjust = 0, vjust = 1)
print(sp)
How to put a wordcloud in a grob?
It shouldn't be that difficult to adapt the code in wordcloud
to construct the data need to fill in a text.grob in grid. The wordcloud
code sends x, y, text and rot values to the base text
function after a window with limits of 0,0 and 1, 1 is specified.
I needed to add this before the for-loop:
textmat <- data.frame(x1=rep(NA, length(words)), y1=NA, words=NA_character_,
rotWord=NA, cexw=NA, stringsAsFactors=FALSE )
This at the end of the for-loop:
textmat[i, c(1,2,4,5) ] <- c(x1=x1, y1=y1, rotWord=rotWord*90, cexw = size[i] )
textmat[i, 3] <- words[i]
And needed to amend the call to .overlap
, because it is apparently not exported:
if (!use.r.layout)
return(wordcloud:::.overlap(x1, y1, sw1, sh1, boxes))
And I returned it invisibly after the loop was complete:
return(invisible(textmat[-1, ])) # to get rid of the NA row at the beginning
After naming it wordcloud2:
> tmat <- wordcloud2(c(letters, LETTERS, 0:9), seq(1, 1000, len = 62))
> str(tmat)
'data.frame': 61 obs. of 5 variables:
$ x1 : num 0.493 0.531 0.538 0.487 ...
$ y1 : num 0.497 0.479 0.532 0.475 ...
$ words : chr "b" "O" "M" ...
$ rotWord: num 0 0 0 0 0 0 0 0 0 ...
$ cexw : num 0.561 2.796 2.682 1.421 ...
draw.text <- function(x,y,words,rotW,cexw) {
grid.text(words, x=x,y=y, rot=rotW, gp=gpar( fontsize=9*cexw)) }
for(i in 1:nrow(tmat) ) { draw.text(x=tmat[i,"x1"], y=tmat[i,"y1"],
words=tmat[i,"words"], rot=tmat[i,"rotWord"],
cexw=tmat[i,"cexw"]) }
As suggested:
with(tmat, grid.text(x=x1, y=y1, label=words, rot=rotWord,
gp=gpar( fontsize=9*cexw)) } # untested
Related Topics
Drawing a Stratified Sample in R
Using Rvest to Scrape a Website W/ a Login Page
R Shiny - Uioutput Not Rendering Inside Menuitem
Does Installing Blas/Atlas/Mkl/Openblas Will Speed Up R Package That Is Written in C/C++
Replace Missing Values with a Value from Another Column
How to Merge Two Data Frames in R by a Common Column with Mismatched Date/Time Values
Loading Dplyr After Plyr Is Causing Issues
How to Combine Multiple .CSV Files in R
Arranging Arrows Between Points Nicely in Ggplot2
Ggplot with Customized Font Not Showing Properly on Shinyapps.Io
How to Use a Character Vector of Column Names in the Formula Argument of Dcast (Reshape2)
Replace Rbind in For-Loop with Lapply? (2Nd Circle of Hell)
How to Create a Line Plot with Groups in Base R Without Loops
Remove Certain Legend Variables and Legend Values from Ggplot2
How to Plot Igraph Community with Defined Colors