How to position annotate text in the blank area of facet ggplot - r

How to annotate some text in the blank space within a odd numbered faceted ggplot.
Lets have a faceted ggplot with data as below with with 2 rows and 2 columns. So there is blank space in place of 2 row, 2nd column.
df<- data.frame(Ara = rep("XTX", each = 3),
Len = c(744, 750, 755),
Mon = c("Sep", "Oct","Nov"),
Value=c(11.224,10.15,4.23))
df
facetplot<-ggplot(df, aes(x=Value, y=Len, shape=Ara))+
geom_point(size=5.0)+
theme(legend.position = c(.7, .4), legend.direction="vertical")+
facet_wrap(~Mon,scales="free_x", nrow=2)
facetplot
Now i am trying to annotate some text in the space but could not ( as written in red in the image). I am looking for something similar to legend.position for annotated text. Do anyone has any idea on this.Or what would be the possible work around.
Thank you.

After you create your plot, simply use
print(facetplot)
grid.text("your text", x = 0.75, y = 0.25)
See ?grid.text for details on positioning. The default coordinate system is the entire screen device with (0,0) as the lower left and (1,1) as the upper right.

To modify the graphical parameter setting for grid.text such as font color, family, fontface and size ...
grid.text("your text", x = 0.6, y = 0.15, gp = gpar(col="red", fontsize = 20, family = "Times", fontface = "italic"))

Related

How to reduce the vertical white space between plots using ggarrange in r

I had trouble trying to remove the vertical white space between each plot. I have several plots so I used ggarrange to combine them.
This is my code:
figure <- ggarrange(lima_exceso,loreto_exceso,amazonas_exceso,madre_exceso,
callao_exceso,apurimac_exceso,ancash_exceso,
sanmartin_exceso, ica_exceso,ayacucho_exceso,
arequipa_exceso, piura_exceso,junin_exceso,pasco_exceso,
cusco_exceso,lambayeque_exceso,huancavelica_exceso,
puno_exceso,tumbes_exceso,lalibertad_exceso,
tacna_exceso,huanuco_exceso,cajamarca_exceso,
labels = c(""),
ncol = 4, nrow = 6)
annotate_figure(figure,
top = text_grob("Exceso de fallecidos (media móvil-7d)",
color = "black", face = "bold", size = 12),
bottom = text_grob("Data source: \n Minsa ",
color = "black", hjust = 0, x = 0, face = "italic",
size = 8), fig.lab = "", fig.lab.face = "bold",
fig.lab.pos = "top.right" , fig.lab.size = 8)
ggsave(file="ex31.pdf" , height = 350, units = "mm" , width = 340)
This is the outcome:
As you can see there is a lot of vertical space between the graphics and that's why the title is too close from the plots. The margin of the pdf is tiny.
So I tried to narrow that space by setting margins for each plot (just for the first column), however, the outcome was not what I wanted.
I add this line code to the plots of the first column:
+theme(plot.margin = unit(c(-0.25,0.5,-0.25,0.5), "lines"))
This was the outcome:
As you can see I narrowed the vertical space but now the plots of the first column are taller than the others, and the title of the first plot (right corner) is too close from the ggarrange title. I want to reduce the space between the plots but I don't want to modify anything else.
Is there a way to reduce the vertical space of my plots using ggarrange?

R: tmap Legend Formatting

I am trying to create a function to map different variables for a specific state's school districts. However I a running into some problems formatting the legend. At the moment I have it laid out the best way to fit the maps(horizontally), but some of the text is being cut off (Below Average Poverty Rate), and I'd like to add % to the number labels in the legend. My code and an image of the legend is below. Any help you can provide would be very much appreciated. Thank You.
MakeLEAMap <-function(StateNum,NCHE_VAR,VAR1_NAME,In,Folder){
as.character(substitute(StateNum))
as.character(substitute(NCHE_VAR))
as.character(substitute(NCHE_In))
as.character(substitute(VAR1_NAME))
as.character(substitute(Folder))
map <-
tm_shape(LEA_1415_New[LEA_1415_New#data$STATEFP == StateNum, ]) +
tm_polygons(NCHE_VAR,border.col="#000000", lwd= .5, textNA="Below Average \nPoverty Rate" , palette = 'Blues', style="quantile",
title=paste(In," State LEA Map: ",VAR1_NAME),
legend.is.portrait = FALSE) +
tm_text("LCITY", size=NCHE_VAR,scale=.8, root=2,print.tiny = FALSE, size.lowerbound = .85, bg.alpha = .75,
remove.overlap = TRUE,legend.size.show = FALSE, col="black") +
tm_layout( legend.title.size = 3,
frame = FALSE, inner.margins = c(0,.0,.05,.0), asp = 1.5,
legend.text.size = 1,
legend.outside=TRUE, legend.outside.position = 'bottom',
legend.frame = TRUE,
legend.outside.size = .3, legend.position = c(-0.1, 0.3))
save_tmap(map, filename=paste("State_Maps_TEST/",Folder,"/",In,".pdf", sep = ''),width=8, height=8 )
}
MakeLEAMap("48","Abv_Diff_Home_Pov","% Children in Poverty minus \n% Children HCY (Ages5-17)",
"TX","ALL")
Here is what the legend looks like now
To make the legend show percentages use this function inside your tm_polygons call:
legend.format=list(fun=function(x) paste0(formatC(x, digits=0, format="f"), " %"))
You can play with the digits (decimal points) and you can drop the space before % sign if you desire.
To make the legend more legible increase the space around your map by making a bigger bbox (possibly using extent function from raster package to read bbox of your spatial object and then enlarging it) and move the legend by adjusting its position.
This is what I came up with in a different context, but one which also called for a percentage sign in tmap legend.

How to change the legend title and position in a lattice plot

I'm using lsmip from lsmeans to plot my model,
library(lsmeans)
PhWs1 <- lsmip(GausNugget1, Photoperiod:Ws ~ Month,
ylab = "Observed log(number of leaves)", xlab = "Month",
main = "Interaction between Photoperiod and Water stress over the months (3 photoperiods)",
par.settings = list(fontsize = list(text = 15, points = 10)))
but I was not able to get a suggestion on the internet on how to handle the legend position, size, title, etc.
I used trellis.par.get() to see the parameters but I could not find the one related to my issue. As you can see from the graph, the legend should be "Photoperiod*Ws" but Ws is not visible.
I see two possibly complementing alternatives to approach this issue. The first would be to create a fully customized legend and pass it on to the key argument of xyplot (which lsmip is heavily based on). Here is an example taken from ?lsmip to clarify my point.
## default trellis point theme
trellis_points <- trellis.par.get("superpose.symbol")
## create customized key
key <- list(title = "Some legend title", # legend title
cex.title = 1.2,
x = .7, y = .9, # legend position
points = list(col = trellis_points$col[1:2], # points
pch = trellis_points$pch[1:2],
cex = 1.5),
text = list(c("A", "B"), cex = .9)) # text
## create results and extract lattice plot
d <- lsmip(warp.lm, wool ~ tension, plotit = FALSE,
main = "Some figure title", key = key)
p <- attr(d, "lattice")
p
As you can see, setting up a customized legend let's you modify all the different components of the legend - including labels, text and symbol sizes, legend spacing, etc. Have a deeper look at the key argument described in ?xyplot which describes the various modification options in detail.
Now, if you have a long legend title and you do not want to include the legend inside the plot area, you could also define separate viewports, thus allowing the legend to occupy more space at the right margin. Note the use of update to remove the initially created legend from p and the subsequent assembly of the single figure components using grid functionality.
## remove legend from figure
p <- update(p, legend = NULL)
## assemble figure incl. legend
library(grid)
png("plot.png", width = 14, height = 10, units = "cm", res = 300)
grid.newpage()
## add figure without legend
vp0 <- viewport(x = 0, y = 0, width = .75, height = 1,
just = c("left", "bottom"))
pushViewport(vp0)
print(p, newpage = FALSE)
## add legend
upViewport(0)
vp1 <- viewport(x = .7, y = 0, width = .3, height = 1,
just = c("left", "bottom"))
pushViewport(vp1)
draw.key(key, draw = TRUE)
dev.off()

Combine different key element types (rectangles, lines, ...) in lattice plot in R

At first I thought this would be trivial, but I could not figure out how to combine rectangles with lines in the legend of a lattice plot. Consider the following example:
library(latticeExtra)
xyplot(rnorm(10) ~ 1:10,
key=list(rectangles=list(size=2, border=F),
text=list(c("Zero", "One", "Two"), col="black"),
col=c("black", "lightgrey", "darkgrey"), divide=1, columns=1,
x=0.01, y=0.95, corner=c(0,1) ),
panel=function(x,...){
panel.abline(v=3, lty="dashed")
panel.xblocks(x,x>5, col="lightgrey")
panel.xblocks(x,x>7, col="darkgrey")
panel.xyplot(x, ...) } )
Instead of 3 rectangles, I would like to have 2 rectangles filled with the appropriate colours, and one dashed line above or below these two rectangles. If I provide a lines argument, then both lines and rectangles will be drawn for all elements (i.e. there will be 2 rectangles and 2 lines simultaneously next to each other).
How can I set up the legend key so that I get this mix of "symbols"? That is, how can I get one dashed line and two rectangles with the appropriate text and colours?
Any help is greatly appreciated! My apologies if this is trival. Please help me see the obvious! :)
This is a rather late answer but it is something I still do. One approach is to use auto.key in the function and then modify the lattice object with update(obj, key = newKey). A more general approach, as suggested by #josh-obrien, is to use the grid functions that under lattice. However, this typically requires empirical tweaking of the coordinates as can be seen in the need to use 3 decimal places of precision to place the dashed lines.
# relative position may be sensitive to absolute sizes
library(latticeExtra)
dev.new(width = 5, height = 5)
set.seed(1234)
# same code as in question, re-written a little bit
# using "transparent" for the 1st of the three rectangles
# using a grid call in the panel function to place the dashed line
xyplot(rnorm(10) ~ 1:10,
key = list(rectangles = list(size = 2, border = FALSE,
col = c("transparent", "lightgrey", "darkgrey")),
text = list(c("Zero", "One", "Two"), col = "black"),
columns = 1, corner = c(0.01, 0.95)),
panel = function(x,...) {
panel.abline(v = 3, lty = "dashed")
panel.xblocks(x, x > 5, col = "lightgrey")
panel.xblocks(x, x > 7, col = "darkgrey")
panel.xyplot(x, ...)
grid::grid.lines(c(0.04, 0.07), c(0.935, 0.935),
gp = gpar(lty = "dashed", col = "black"))
}
)
[![plot with combined elements in legend][1]][1]
[1]: https://i.stack.imgur.com/K7AJN.png

GNU R, VennDiagram, and making a complement diagram

I have been working on Venn Diagrams in GNU R. I have tried using the packages venneuler and VennDiagram. I find that VennDiagram has a lot more granular control, but it seems to lack the documentation to fill in all the details. The closest I can find is this PPT file.
http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3041657/bin/1471-2105-12-35-S4.PPT which I found from the URL: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3041657/
Here are my issues with using VennDiagram.
For the code
require(VennDiagram)
venn.diagram(list(B = 1:2000, A = 200:400),fill = c("yellow", "blue"),
alpha = c(0.8, 0.8), cex =1.5, cat.pos=0, cat.fontface = 4,
lty = 1, fontfamily =3, filename = "test001.jpeg");
(I had an image here, but since I am new I do not have rights to post the image. Please generate the image from the code above.)
I can make a subset (hence a circle within a circle). But I am not finding a way to do the following:
Make BC to show as the equal of B^C. No, a literal "B^C" does not work. I would think there is a way to relabel the sets in a different property, but I have not seen a way to do it.
To position the labels of B^C and A^C within the sets and not on the outside as currently shown. I tried cat.pos="inner" but that way not a valid property. I also tried cat.pos=c(0,0) in the hope that I could feed it as an X,Y where X & Y are from the center of the circle, but it did not produce any different results.
Thanks to DWin, here is the code to complete my diagram to the exercise.
Suppose that A ⊂ B. Show that Bc ⊂ Ac.
require(VennDiagram)
plot.new()
venn.plot <- venn.diagram(
x = list(B = 1:200, A = 20:40), category.names= expression(B, A),
fill = c("yellow", "blue"), alpha = c(0.8, 0.8), cex =1.5,
cat.pos=0, cat.dist=c(-.1, -.1), filename = NULL) ;
grid.draw(venn.plot); # grid graphic requires explicit print or draw operation
grid.text(expression(B^c),x=0.2,y=0.95)
grid.text(expression(A^c),x=0.16,y=0.95)
grid.text(expression(A^c),x=0.16,y=0.75)
Perhaps something like this:
venn.diagram(list(B = 1:200, A = 20:40), category.names= expression(B^c, A),
fill = c("yellow", "blue"), alpha = c(0.8, 0.8), cex =1.5, cat.pos=0,
cat.dist=c(.1, -.1), cat.fontface = 4,lty = 1, fontfamily =3,
filename = "test001.jpeg")
To get the labels inside the circles, supply 'cat.dist' with negative values. The trick is that the reference point is radial distance from the boundary at 12 o'clock rather than from the center. The documentation says that the category.names argument is interpreted with plotmath syntax. The superscript operation in plotmath is done with the "^" operator. I have here moved the A" inside while leaving the B^c outside to suggest that it is the area outside the B circle that is being labeled. (I also improved the plotting time by making the example smaller.) I tried drawing three labels but that does not seem to "part of the package".
Here's a way you can annotate with grid.text() on the screen device:
plot.new()
venn.plot <- venn.diagram(
x = list(B = 1:200, A = 20:40), category.names= expression(B^c, A),
fill = c("yellow", "blue"), alpha = c(0.8, 0.8), cex =1.5,
cat.pos=0, cat.dist=c(.05, -.1), filename = NULL) ;
grid.draw(venn.plot); # grid graphic requires explicit print or draw operation
grid.text("B",x=0.8)
# then you can save to file

Resources