I'm trying to fix the position of some text in a rasterVis::vectorplot so that it stays in the same position even if I change the width and height of the png file.
I tried using the margin parameters of par but with no luck.
This is an example of what I got so far:
#Some raster data
proj <- CRS('+proj=longlat +datum=WGS84')
df <- expand.grid(x = seq(-2, 2, .01), y = seq(-2, 2, .01))
df$z <- with(df, (3*x^2 + y)*exp(-x^2-y^2))
r <- rasterFromXYZ(df, crs=proj)
#[A]
png("test01.png",width = 918,height = 850,res=100)
vectorplot(r,par.settings=list(layout.widths = list(axis.key.padding = 3)),
narrows = 500,length=0.1,lwd.arrows=0.4)
grid.text(substr(R.version.string, 1, 15),rot=90, x=0.92,y=0.14,gp = gpar(fontsize = 12, fontface = "italic"))
dev.off()
This is the output of [A]. That's how I want it:
Now, changing the width and height:
##[B]
png("test02.png",width = 1718,height = 850,res=100)
vectorplot(r,
par.settings=list(layout.widths = list(axis.key.padding = 3)),
narrows = 500,length=0.1,lwd.arrows=0.4)
grid.text(substr(R.version.string, 1, 15),rot=90, x=0.92,y=0.14,gp = gpar(fontsize = 12, fontface = "italic"))
dev.off()
This is the output of [B]:
As you can see the text doesn't stay in the same place. (I'm new with the rasterVis library.)
The layer function of the latticeExtra package with panel.text will help you here. The panel.text functions prints inside the area of the panel, so you have to add the option clip = list(panel = FALSE) to the settings list in order to print outside this area:
library(grid)
library(rasterVis)
vectorplot(r,par.settings=list(clip = list(panel = FALSE),
layout.widths = list(axis.key.padding = 3)),
narrows = 500,length=0.1,lwd.arrows=0.4) +
layer(panel.text(2.05, -2,
substr(R.version.string, 1, 15),
adj = c(0, 1),
srt = 90))
Related
As shown in the map below, how can I place the legend to the last cell in the grid?
The code I used is
psp1 <- tm_shape(province) +
tm_borders(col = 'black') +
tm_shape(county) +
tm_polygons(col = 'estimate', title = 'Changes in %', style = 'fixed', palette = brewer.pal(n = 6, name = 'Spectral'),
breaks = c(-15, -10, -5, 0, 5, 10, 15), legend.hist = F) +
tm_facets('warming', ncol = 2) +
tm_shape(province) +
tm_borders(col = 'black') +
tm_compass(north = 0, type = 'arrow', show.labels =0, position = c('right','top')) +
tm_layout(legend.format = list(fun = function(x) formatC(x, digits = 1, format = "f")),
fontface = 'bold',
legend.text.size = 1.3,
legend.width = 0.2,
legend.title.size = 1.5,
panel.label.size = 1.5,
panel.label.fontface = 'bold')
The data can be found from here. Thanks.
My answer comes perhaps a little late... (almost one year after your request!) Anyway, your question is very interesting and I hope this answer will be useful, either now or for future projects, for you or other SO users (by the way, thanks for having kept your input data accessible for a year ;-)).
As far as I know, it is not possible to solve your problem by using the tm_facets() function of the tmap library. So I suggest a slightly different "strategy" (still using the tmap library) to get what you are looking for.
It is articulated in two steps:
Build the maps and the legend manually... fortunately, not quite manually since the solution I suggest uses one custom function (i.e. make_graph()) that is run through a Map() function.
Edit the map mosaic with the legend using the R base grid library. Again, the implementation is made easier by the use of one custom function (i.e. Maps_setup()) run through a Map() function.
So, please find below a reprex that details the approach.
Reprex
STEP 1 - BUILDING THE MAPS AND THE LEGEND
library(sf)
library(tmap)
library(RColorBrewer)
# Import data
province <- st_read("province.shp")
county <- st_read("county.shp")
# Split the 'sf' object 'county' into a list of five 'sf' objects corresponding
# to the five warming scenarios (i.e. the first five facets of the final figure)
county_warm_list <- split(county , f = county$warming)
# Build the function 'make_graph' to generate the maps
make_graph <- function(x,y){
results <- tm_shape(x,
is.master = TRUE) +
tm_polygons(col = 'estimate',
title = 'Changes in %',
style = 'fixed',
palette = brewer.pal(n = 6, name = 'Spectral'),
breaks = c(-15, -10, -5, 0, 5, 10, 15),
legend.hist = FALSE,
midpoint = 0) +
tm_shape(province) +
tm_borders(col = 'black') +
tm_compass(north = 0,
type = 'arrow',
show.labels = 0,
position = c(0.93, 0.87),
size = 1.2) +
tm_layout(legend.show = FALSE,
# NB: the use of the 'get_asp_ratio()' function enables
# to optimize the size of each map inside its own facet:
asp = tmaptools::get_asp_ratio(x),
panel.labels = y,
panel.label.size = 0.8,
panel.label.fontface = 'bold',
inner.margins = c(0.02, 0.02, 0.02, 0.02))
return(results)
}
# Run the 'make_graph()' function through the list of the five 'sf' objects (i.e.
# 'county_warm_list') to generate the maps with their respective title using
# the 'Map()' function
map_titles <- names(county_warm_list)
Maps_list <- Map(make_graph, county_warm_list, map_titles)
# Build the legend using only the object "county"
Maps_legend <- tm_shape(county) +
tm_polygons(col = 'estimate',
title = 'Changes in %',
style = 'fixed',
palette = brewer.pal(n = 6, name = 'Spectral'),
breaks = c(-15, -10, -5, 0, 5, 10, 15),
legend.hist = FALSE,
midpoint = 0) +
tm_layout(legend.only = TRUE,
legend.position = c("center", "center"),
legend.format = list(fun = function(x) formatC(x, digits = 1, format = "f")),
fontface = 'bold',
legend.text.size = 1.3,
legend.width = 0.2,
legend.title.size = 1.5)
# Add the legend to 'Maps_list'
Maps_list$Legend <- Maps_legend
At the end of this first step, you get a list (i.e. Maps_list) containing 6 elements (i.e. five maps and one legend).
STEP 2 - LAYOUT OF THE MOSAIC OF MAPS WITH THE LEGEND
library(grid)
grid.newpage()
# Build the function 'Maps_setup' to set up the layout
Maps_setup <- function(x,y,z){
pushViewport(viewport(layout = grid.layout(nrow = 3, ncol = 2,
widths = unit(7.32, "cm"),
heights = unit(5, "cm"))))
setup <- print(x, vp = viewport(layout.pos.row = y, layout.pos.col = z))
return(setup)
}
# Run the 'Maps_setup()' function through the six objects of 'Maps_list' (i.e.
# 5 maps + 1 legend) to place the maps and the legend on the page using
# the 'Map()' function
# The 'pos_row' and 'pos_col' vectors are used to indicate where to place the
# maps as the 'Maps_setup()' function works through the list
pos_row <- rep(1:3, each = 2)
pos_col <- rep(1:2, times = 3)
Final_Results <- Map(Maps_setup, Maps_list, pos_row, pos_col)
Created on 2022-01-25 by the reprex package (v2.0.1)
I am trying to add multi color text in a title in one of our plots.
I have a grid layout that has one viewport, I am using gridtext as it makes it easy to add html and style the text, however I am not able to place it in the existing viewport.
Can you let me know how would I be able to do that?
titleFunction <- function() {
library(ggplot2)
library(gridExtra)
library(grid)
library(gridtext)
textSizeMajor = 36
textSizeMinor = 32
mainLO <- grid.layout(nrow = 4, ncol = 3,
widths = unit(c(textSizeMajor * 1.2, 1, .5),
c("points", "null", "cm")),
heights = unit(c(textSizeMajor, textSizeMajor, 40, 1),
c("points", "points", "points", "null")))
pushViewport(viewport(name="mainViewPort", layout = mainLO))
fontface = "bold"
# Main title
grid.text("Main Title",
vp = viewport(layout.pos.col = 2, layout.pos.row = 1),
gp=gpar(fontsize=26, fontface = fontface))
browser()
grid.draw(richtext_grob(text = '<span style="color:red">Hello</span>, <span style="color:blue">World</span>!'))
# Want to place this below Main title, where row = 2
# vp = viewport(layout.pos.col = 2, layout.pos.row = 2)
# main viewport pop
popViewport(1)
}
The main issue was dealing with the grid and textGrob objects. Here is the code that works
print(grid.draw(richtext_grob(text = subTitle,
gp = gpar(fontsize=22),
vp = viewport(layout.pos.col = 2, layout.pos.row = 2))) )
I am creating a multi panel figure that includes a ComplexHeatmap object so I am using multi_panel_figure() instead of ggarrange().
I have tried to include an argument to set the labels manually as I do in ggarrange but it does not work.
ggarrange(...,
font.label = list(size = 14, color = "black", face = "bold", family = NULL))
Like this:
Figure2 = multi_panel_figure(width = 360, height = 180,
columns = 3, rows = 1,
font.label = list(size = 24))
Figure2 %<>% fill_panel(DE_HM, column = 1)
Figure2 %<>% fill_panel(DE_TM, column = 2:3)
save_multi_panel_figure(figure = Figure2,
filename = "Figure2.svg")
I am quite new using ggplot2 so I do not know very well how to control the text size proportions. In this case I would like to make the labels bigger as I need to make the figure large so other text in it can be read easily. Maybe I should generate my figure any other way?
Here is how the labels look like right now (panel B need to be large so text can be read in the treemap):
With trace(fill_panel, edit=T) change the function fill_panel() on line 124 from:
panel_label <- textGrob(label = label, x = 1, y = 0, just = label_just)
to:
panel_label <- text_grob(label = label, x = 1, y = 0, just = label_just, face = "bold", size = 14)
also use library(ggpubr) in order to make this work.
I'm using ComplexHeatmap to create a heatmap in R. I have recreated a small heatmap here. I can't figure out from the documentation how to adjust the font size for the text on the x-axis.
a = matrix(1:9, nrow = 3, ncol = 3)
rownames(a) = c("alphabet","xylophone","tornado")
colnames(a) = c("c1","c2","c3")
my_heatmap = ComplexHeatmap::Heatmap(
matrix = t(a),
col = RColorBrewer::brewer.pal(9, "RdBu"))
This code produces this:
I want to adjust the font size for the c("alphabet","xylophone","tornado") text so that it is much smaller. How do I do this?
You can use row_names_gp and column_names_gp to adjust y-axis and x-axis labels, respectively.
# if (!requireNamespace("BiocManager", quietly = TRUE))
# install.packages("BiocManager")
# BiocManager::install("ComplexHeatmap")
#
# library(ComplexHeatmap)
# library(grid)
a = matrix(1:9, nrow = 3, ncol = 3)
rownames(a) = c("alphabet","xylophone","tornado")
colnames(a) = c("c1","c2","c3")
ComplexHeatmap::Heatmap(
matrix = t(a),
col = RColorBrewer::brewer.pal(9, "RdBu"),
column_names_gp = grid::gpar(fontsize = 8),
row_names_gp = grid::gpar(fontsize = 8))
I am trying to save a ggplot2 plot using the cairo_pdf() function, but the markers of the dotted geom_line() keep getting stretched. Please see sample code and output below.
library(ggplot2)
df <- data.frame(x = 0:10, y = 0:10)
p <- ggplot(data = df) +
geom_line(aes(x, y), linetype = 3, size = 2, lineend = "round")
ggsave("ggsave.pdf", width = 7, height = 5)
pdf("pdf.pdf", width = 7, height = 5)
print(p)
dev.off()
cairo_pdf("cairo_pdf.pdf", width = 7, height = 5)
print(p)
dev.off()
Output using ggsave() with markers nice and round:
Output using pdf() same as ggsave().
Output using cairo_pdf() with markers stretched and spacing between markers wrong:
Is there any way to make the cairo_pdf() output, specifically the geom_line(), look like the the other PDFs? I would like to use cairo_pdf() since it has some other benefits that really help with my work. Any help would be appreciated.
EDIT: I have the same problem using R base graphics. For instance:
pdf("r_base_pdf.pdf")
plot(x = c(0, 1), y = c(0, 1), type = "l", lty = "11", lwd = 5)
dev.off()
cairo_pdf("r_base_cairo.pdf")
plot(x = c(0, 1), y = c(0, 1), type = "l", lty = "11", lwd = 5)
dev.off()