I am trying to build a map that contains a few points overlayed onto rivers. I am using code adapted from https://milospopovic.net/map-rivers-with-sf-and-ggplot2-in-r/, but I downloaded the North America map and substituted
st_polygon(list(cbind(
c(-84.9, -84.9, -84.0, -84.0, -84.9),
c(34.4, 35.05, 35.05, 34.4, 34.4)
))),
crs = crsLONGLAT)
to create my bounding box.
test.point <- data.frame("x"= -84.73405, "y"= 35.00988)
p <-
ggplot()+
geom_point(data= test.point, aes(x=x, y=y), color= "black", fill= "black") +
geom_sf(data=na_riv, aes(color=factor(ORD_FLOW), size=width)) +
coord_sf(crs = 4087,
xlim = c(bbox["xmin"], bbox["xmax"]),
ylim = c(bbox["ymin"], bbox["ymax"])) +
labs(x= "", subtitle="",
title="Rivers of the Southeast",
caption="©2022\nSource: ©World Wildlife Fund, Inc. (2006-2013)\n HydroSHEDS database http://www.hydrosheds.org") +
scale_color_manual(
name = "",
values = c('#081f6b', '#08306b', '#08519c', '#2171b5', '#4292c6', '#6baed6', '#9ecae1', '#c6dbef', '#deebf7')) +
scale_size(range=c(0, .3)) +
scale_alpha_manual(values=c("2"= 1, "3" = 1, "4" = 1, "5" = .7, "6" = .6, "7" = .4, "8" = .3, "9" = .2, "10" = .1)) +
theme_bw() +
theme(text = element_text(family = "georg"),
panel.background = element_blank(),
legend.background = element_blank(),
legend.position = "none",
panel.border = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major = element_blank(),
plot.title = element_text(size=40, color="#2171b5", hjust=0.5, vjust=0),
plot.subtitle = element_text(size=14, color="#ac63a0", hjust=0.5, vjust=0),
plot.caption = element_text(size=10, color="grey60", hjust=0.5, vjust=10),
legend.text = element_text(size=9, color="grey20"),
legend.title = element_text(size=10, color="grey20"),
strip.text = element_text(size=12),
plot.margin = unit(c(t=1, r=0, b=-1, l=-1),"lines"))
p
The above code yields a pretty map of all of the rivers but the point doesn't show up. :(
Here is one way to get around this. Basically you can convert the points you want to highlight a a simple feature geometry:
test.point <- data.frame(x = c(-84.73405, -84.6), y = c(35.00988, 34.6))
new_test.point <- st_sfc(st_multipoint(as.matrix(test.point)), crs = crsLONGLAT)
Then, I just filtered the data to have only the rivers present in the area of interested:
nariv = nariv %>% mutate(inter = as.integer(st_intersects(geometry, bbox)))
nariv_filt = nariv %>% filter(!is.na(inter))
And create the plot:
ggplot() +
geom_sf(data = nariv_filt, aes(color = factor(ORD_FLOW), size = width, alpha = width)) +
geom_sf(data = new_test.point, color="red", size=5)+
coord_sf(crs = prj, xlim = c(bb["xmin"], bb["xmax"]),ylim = c(bb["ymin"], bb["ymax"])) +
geom_point(data = test.point, aes(x=x, y=y), color="red", size=5)+
labs(y = "", subtitle = "", x = "", title = "Rivers of North and Central America") +
scale_color_manual(name = "",
values = c(
"#08306b", "#1c4680", "#305d94", "#4574a7",
"#5d8cb9", "#77a4cb", "#deebf7", "#deebf7", "#deebf7"
), drop = F) +
scale_alpha(range = c(0.3, 0.8)) +
scale_size(range = c(0, 3)) +
theme_minimal() +
theme(
text = element_text(family = "Montserrat"),
panel.background = element_blank(),
legend.background = element_blank(),
legend.position = "none",
panel.border = element_blank(),
#panel.grid.minor = element_blank(),
#panel.grid.major = element_blank(),
#plot.title = element_text(size = 100, color = "#2171b5", hjust = 0.5, vjust = -22),
#plot.subtitle = element_text(size = 14, color = "#ac63a0", hjust = 0.5, vjust = 0),
#plot.caption = element_text(size = 40, color = "grey60", hjust = 0.5, vjust = 120),
#axis.title.x = element_text(size = 10, color = "grey20", hjust = 0.5, vjust = -6),
legend.text = element_text(size = 9, color = "grey20"),
legend.title = element_text(size = 10, color = "grey20"),
strip.text = element_text(size = 12),
#plot.margin = unit(c(t = -2.5, r = -10, b = -10, l = -10), "lines"),
axis.title.y = element_blank(),
axis.ticks = element_blank(),
#axis.text.x = element_blank(),
#axis.text.y = element_blank()
)
Related
I want to add this basemap using to raster using ggplot2 and terra packages and I am stuck.
Can I have some help figuring this out?
library(basemaps)
library(terra)
Library(rasterVis)
set_defaults(Yiel_total , map_service = "esri" , map_type = "world_hillshade")
x <- basemap_magic(Yiel_total , map_service = "esri" , map_type = "world_hillshade")
#Yiel_total was used for the extent
SpatRaster Data for Yiel_total
The ggplot code:
Yield <-rast("Yield_total")
Yield_Tot_6 <- gplot(Yield ) + geom_tile(aes(fill = value)) + ggtitle("")+
theme(panel.spacing.x=unit(0,"lines"), axis.title.x = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
axis.title.y = element_blank(),plot.title = element_text(hjust = 0.5, size = 18, face = "bold"),strip.background = element_blank(),
strip.text = element_text(size = 14, color = "black", face = "bold"),legend.text = element_text(size = 14, face = "bold"),
legend.title = element_text(hjust = 0.1, size = 16, face = "bold"), panel.background = element_blank()) +
guides(fill = guide_colourbar(title = "Relative yield",title.hjust = 0.5, barheight = 15, barwidth = 2))+
#basemap_magic(Yield_0.5_6, map_service = "esri" , map_type = "world_hillshade")+
facet_wrap(~ variable, ncol = 3 ) +
scale_fill_gradient(limits = c(0.01,0.88),low = 'red', high = 'dark green', na.value = "grey93", breaks = c(0.02,0.20, 0.40, 0.60,0.75, 0.87))
Yield_Tot_6
You can use tidyterra to work easily with ggplot2 and SpatRasters. I modified the call to basemap_raster and converted it also to SpatRaster:
library(basemaps)
library(terra)
Yiel_total <- rast("Yiel_total.tif")
set_defaults(Yiel_total, map_service = "esri", map_type = "world_hillshade")
x <- basemap_raster(Yiel_total, map_service = "esri", map_type = "world_hillshade")
x_terr <- rast(x)
library(ggplot2)
library(tidyterra)
ggplot() +
geom_spatraster_rgb(data = x_terr) +
geom_spatraster(data = Yiel_total) +
# Faceting with tidyterra
facet_wrap(~lyr, ncol = 3) +
scale_fill_gradient(
limits = c(0.01, 0.88), low = "red", high = "dark green",
na.value = NA, breaks = c(0.02, 0.20, 0.40, 0.60, 0.75, 0.87)
) +
ggtitle("") +
theme(
panel.spacing.x = unit(0, "lines"), axis.title.x = element_blank(),
axis.text = element_blank(), axis.ticks = element_blank(),
axis.title.y = element_blank(), plot.title = element_text(
hjust = 0.5,
size = 18, face = "bold"
), strip.background = element_blank(),
strip.text = element_text(size = 14, color = "black", face = "bold"),
legend.text = element_text(size = 14, face = "bold"),
legend.title = element_text(hjust = 0.1, size = 16, face = "bold"),
panel.background = element_blank()
) +
guides(fill = guide_colourbar(
title = "Relative yield", title.hjust = 0.5,
barheight = 15, barwidth = 2
))
I have adapted the solution to align forest plot and a table from this post:
how to align table with forest plot (ggplot2)
Here is my code:
library(dplyr, warn = FALSE)
library(ggplot2)
library(patchwork)
tester <- data.frame(
treatmentgroup = c("Education Continuous", "0", "1-4",
"5-8", ">8"),
or = c(0.914, 0.961, 0.709, 0.523, 0.457),
low_ci = c(0.894, 0.793, 0.577, 0.389, 0.339),
up_ci = c(0.935, 1.166, 0.871, 0.708, 0.616),
OR_ci = c(
"0.914 (0.894; 0.935)", "0.961 (0.793; 1.166)", "0.709 (0.577; 0.871)",
"0.523 (0.389; 0.708)", "0.457 (0.339; 0.616)"),
ci = c(
"0.894; 0.935",
"0.793; 1.166",
"0.577; 0.871",
"0.389; 0.708",
"0.339; 0.616"),
no = c(1, 2, 3, 4, 5)
)
forest <- ggplot(
data = tester,
aes(x = treatmentgroup, y = or, ymin = low_ci, ymax = up_ci)) +
geom_pointrange(aes(col = treatmentgroup)) +
geom_hline(yintercept = 1, colour = "black") +
xlab("") +
ylab("OR (95% CI)") +
geom_errorbar(aes(ymin = low_ci, ymax = up_ci, col = treatmentgroup), width = 0, cex = 1) +
theme_classic() +
theme(
panel.background = element_blank(), strip.background = element_rect(colour = NA, fill = NA),
strip.text.y = element_text(face = "bold", size = 12),
panel.grid.major.y = element_line(colour = col_grid, size = 0.5),
strip.text = element_text(face = "bold"),
panel.border = element_rect(fill = NA, color = "black"),
legend.position = "none",
axis.text = element_text(face = "bold"),
axis.title = element_text(face = "bold"),
plot.title = element_text(face = "bold", hjust = 0.5, size = 13)
) +
coord_flip()
dat_table <- tester %>%
select(treatmentgroup, OR_ci) %>%
tidyr::pivot_longer(c(OR_ci), names_to = "stat") %>%
mutate(stat = factor(stat, levels = "OR_ci"))
table_base <- ggplot(dat_table, aes(stat, treatmentgroup, label = value)) +
geom_text(size = 3) +
scale_x_discrete(position = "top", labels = "OR (95% CI)") +
labs(y = NULL, x = NULL) +
theme_classic() +
theme(
strip.background = element_blank(),
panel.grid.major = element_blank(),
panel.border = element_blank(),
axis.line = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_text(size = 12),
axis.ticks = element_blank(),
axis.title = element_text(face = "bold"),
)
forest + table_base + plot_layout(widths = c(10, 4))
However, my graph ends up with the categories out of order. How can I adjust the order to this one: Education Continuous, 0, 1-4, 5-8, and >8?
I tried factor(tester$treatmentgroup) but it did not work.
Also, how can I make all the categories the same color (black, for example) instead of one each color? I tried eliminating the line geom_pointrange(aes(col = treatmentgroup)) + but it does not work.
You're right that you can convert treatmentgroup to a factor, you just need to specify the levels. Try running this code before you generate your plots with ggplot().
tester <- tester %>%
mutate(treatmentgroup = factor(treatmentgroup,
levels = c(">8", "5-8", "1-4", "0", "Education Continuous")))
I have 3 multi-plot figures I'm making for a manuscript and R is shrinking the first plot in the 2 figures with 3 paneled plots. They have different axes and scales so I couldn't use a facet function, but ggarrange() does what I need. Is there a way to make the size of the actual graphs identical?enter image description here
Plot 1 axes smaller
Here's the script generating them:
library(ggplot2)
library(ggpubr)
library(ggpmisc)
library(ggrepel)
library(tidyverse)
summary_bp <- read.table("1500bp_amas_summary.txt", header=TRUE)
alignment_length <- summary_bp$Alignment_length
no_inf_sites <- summary_bp$Parsimony_informative_sites
Length_Site_Reg <- ggplot(summary_bp, aes(x=alignment_length, y=no_inf_sites)) +
geom_point(shape = 1, size = 1) +
geom_smooth(method = lm, size = 0.7) +
stat_regline_equation(label.x = 3000, label.y = 3500, geom = "text", aes(label= ..rr.label..), size = 2) +
stat_cor(method = "pearson", label.x = 3000, label.y = 3100,aes(label = ..p.label..), size = 2) +
coord_cartesian(xlim = c(1500, 15000), ylim = c(0,4000)) +
scale_x_continuous(breaks = seq(1500, 15000, by=1500)) +
scale_y_continuous(breaks = seq(0, 4000, by=500)) +
labs( x = "Alignment Lengths", y = "Number of Parsimony \n Informative Sites") +
theme(aspect.ratio = 1, axis.text.x = element_text(angle=45, hjust = 1),
axis.line = element_line(color = "black"), panel.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text = element_text(size = 7),
axis.title.x = element_text(size = 9, face = "bold"), axis.title.y = element_text(size = 8, face = "bold"))
Length_Site_Reg
#Fig. 3b) GC hist
summary_all <- read.table("summary_trim.txt", header=TRUE, sep = ",")
GC_hist <- ggplot(data = summary_all, aes(x=GC_content)) +
geom_histogram(binwidth = 0.025, fill = "white", color = "black") +
xlim(0.3,0.725) +
coord_cartesian( ylim = c(0,1050)) +
labs(x = "GC Content", y = "Number of Orthologs") +
theme(aspect.ratio = 1, panel.background = element_blank(), panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), legend.position = c(0.75, 0.65),
axis.line = element_line(color = "black"), axis.text = element_text(size = 8),
axis.title = element_text(size = 9, face = "bold"), legend.key.size = unit(0.4, 'cm'),
legend.key.height = unit(0.4, 'cm'),
legend.key.width = unit(0.4, 'cm'),
legend.title = element_text(size=6),
legend.text = element_text(size=6)) +
geom_vline(aes(xintercept=mean(GC_content), color="mean"),
linetype="solid", size=0.5, show.legend = FALSE)
GC_hist
# Fig. 3c) K2P Divergence Hist
#trimmed_k2 <- file.choose()
trimmed_k2_data <- read.table("trimmed_alignment_k2.csv", header=TRUE, sep = ",")
trimmed_k2_data
trimmed_k2_data_hist <- ggplot(data = trimmed_k2_data, aes(x=distance)) +
geom_histogram(binwidth = 0.025, fill = "white", color = "black") +
coord_cartesian( ylim = c(0,1200) ) + scale_y_continuous(breaks = seq(0,1200,200)) +
labs(x = "K2P Distance", y = "Number of Orthologs", size= 3) +
theme(aspect.ratio = 1, panel.background = element_blank(), panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(color = "black"),
axis.text = element_text(size = 8),
axis.title = element_text(size = 9, face = "bold")) +
geom_vline(aes(xintercept=mean(distance)), linetype="solid", colour="red", size=0.5, show.legend = FALSE)
trimmed_k2_data_hist
Fig3_plots <-ggarrange(Length_Site_Reg, GC_hist, trimmed_k2_data_hist, ncol = 3, widths = 1, heights = 1)
Fig3_plots
I would like to set the color and the shape of my 2 indicators which has been plotted in in two layes. The scale_color_manual works however the scale_shape_manual is not working. By having or not having this line "scale_shape_manual"; the result is the same and shape "16" (filled circle) is picked up?
comp_graph_1 <- ggplot() +
layer( mapping = aes(x=log(FV), y= msd, colour = "Reference"), #factor(Dataset)
data = ref,
stat = "identity",
geom = "point",
position = "identity")+
layer(mapping = aes(x=log(FV), y= msd, colour = "Target"), # "red" "blue"
data = target, #data = target[Is_Phone == 0],
stat = "identity",
geom = "point",
position = "identity")+
theme(panel.background = element_rect(fill = 'white'),
panel.grid = element_line(colour = "grey90") , panel.ontop = FALSE)+
theme(legend.justification = c(0, 0), legend.position = "bottom",
legend.background = element_rect(), legend.title = element_blank(), legend.key = element_rect(fill = "white"),
legend.text = element_text(size = 9,colour = "#7F7F7F"), panel.border = element_blank(),
axis.line = element_line(color = "#7F7F7F"))+
theme(plot.title = element_text(size = 16, colour = "#7F7F7F"),
axis.title.x = element_text(size = 11, hjust = 1, face = "bold", colour = "#7F7F7F"),
axis.title.y = element_text(size = 11, hjust = 1, face = "bold", colour = "#7F7F7F")) +
ggtitle(paste0(x, " / ", y, " distribution ")) + xlab(paste0("log ", x)) + ylab(y) +
scale_color_manual(values = c("Reference" ="#FFC000","Target" = "#00AEEF")) +
scale_shape_manual(values = c("Reference" =17, "Target" = 4))
I think where you have colour = "Target" you need a shape statement as well
shape = "Target" and shape = "Reference" and it should work.
I have the following code producing a stacked barplot in ggplot
data_age <- data.frame(age = as.factor(c("16 to 20", "21 to 24", "25 to 30", "31 to 40", "40+")),
total = c(740, 1092, 855, 525, 182),
perc_total = c(22, 32, 25, 15, 5))
g_age <- ggplot(data_age , aes(1, perc_total, fill = age, label = perc_total)) +
geom_bar(stat ="identity") +
geom_text(size = 4, position = position_stack(vjust = 0.5), colour = "black") +
coord_flip() +
scale_y_continuous(limits = c(0, 100)) +
scale_x_continuous(limits = c(0, 2), breaks = 1) +
scale_fill_manual(guide = guide_legend(title = NULL, keyheight = 0.5, keywidth = 0.5, direction = "horizontal"), values = c("#FFFFB2", "#FECC5C", "#FD8D3C", "#F03B20", "#BD0026")) +
theme_bw() +
theme(plot.title = element_blank(), axis.title.x = element_blank(), axis.title.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank(),
axis.text.x = element_blank(), axis.ticks.x = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
legend.position="bottom")
Which results in this barplot
However I need the order of the data to be reversed. I can achieve that by doing the following
g_age_2 <- ggplot(data_age , aes(1, perc_total, fill = levels(age)[5:1], label = perc_total)) +
geom_bar(stat ="identity") +
geom_text(size = 4, position = position_stack(vjust = 0.5), colour = "black") +
coord_flip() +
scale_y_continuous(limits = c(0, 100)) +
scale_x_continuous(limits = c(0, 2), breaks = 1) +
scale_fill_manual(guide = guide_legend(title = NULL, keyheight = 0.5, keywidth = 0.5, direction = "horizontal"), values = c("#BD0026", "#F03B20", "#FD8D3C", "#FECC5C", "#FFFFB2")) + ## Inverted the colors too
theme_bw() +
theme(plot.title = element_blank(), axis.title.x = element_blank(), axis.title.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank(),
axis.text.x = element_blank(), axis.ticks.x = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
legend.position="bottom")
And this plot follows the order and the colors that I want, but the legend does not match
How can I solve this?
You could do:
g_age <- ggplot(data_age , aes(1, perc_total, fill = age, label = perc_total)) +
geom_bar(stat ="identity",position = position_stack(reverse = TRUE)) +
geom_text(size = 4, position = position_stack(vjust = 0.5,reverse = TRUE), colour = "black") +
coord_flip() +
scale_y_continuous(limits = c(0, 100)) +
scale_x_continuous(limits = c(0, 2), breaks = 1) +
scale_fill_manual(guide = guide_legend(title = NULL, keyheight = 0.5, keywidth = 0.5, direction = "horizontal"),
values = c("#FFFFB2", "#FECC5C", "#FD8D3C", "#F03B20", "#BD0026")) +
theme_void() +
theme(legend.position="bottom")
Note the addition of position = position_stack(reverse = TRUE) to geom_bar() and to geom_text() as well.
I also replaced the theme with theme_void() to remove everything and just have theme() for setting the position of the legend.