I have a really long y-axis title with scientific notation that I want to wrap and make center aligned. I can either wrap the title and have it left aligned, or center an incorrect format of the title. How can I wrap the axis title AND have it centered in ggplot2?
Example Data
set.seed(321)
df <- data.frame(matrix(ncol = 2, nrow = 3))
colnames(df)[1:2] <- c("date","value")
df$value <- round(rnorm(3, 100,30),0)
st <- as.Date("2020-01-01")
en <- as.Date("2020-03-31")
df$date <- seq.Date(st,en,by = '1 month')
This makes the ggplot2 figure with the unwrapped long y-axis title
library(ggplot2)
ggplot(df, aes(x = date, y = value)) +
geom_point() +
labs(x = "",
y = expression(paste("Here is a really really really looooonnnng title with notation ( ", m^-2,")"))) +
scale_x_date(breaks = seq(st, en, by = "1 month"),
limits = c(st,en),
date_labels = "%b %Y") +
scale_y_continuous(limits = c(0,150),
breaks=seq(0,150,25)) +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16),
axis.text.x = element_text(size = 14, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 14, color = "black"))
I have tried using \n which wraps the title but, the title is not centered, it is left aligned
ggplot(df, aes(x = date, y = value)) +
geom_point() +
labs(x = "",
y = expression(paste("Here is a really really really \n looooonnnng title with notation ( ", m^-2,")"))) +
scale_x_date(breaks = seq(st, en, by = "1 month"),
limits = c(st,en),
date_labels = "%b %Y") +
scale_y_continuous(limits = c(0,150),
breaks=seq(0,150,25)) +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16),
axis.text.x = element_text(size = 14, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 14, color = "black"))
Using str_wrap() centers the title but the title is no longer formatted correctly
library(stringr)
ggplot(df, aes(x = date, y = value)) +
geom_point() +
labs(x = "",
y = str_wrap(
expression(paste("Here is a really really really \n looooonnnng title with notation ( ", m^-2,")")),50)
)+
scale_x_date(breaks = seq(st, en, by = "1 month"),
limits = c(st,en),
date_labels = "%b %Y") +
scale_y_continuous(limits = c(0,150),
breaks=seq(0,150,25)) +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16),
axis.text.x = element_text(size = 14, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 14, color = "black"))
I tried creating a wrapper function based on this similar SO question but it also did not format the title correctly
wrapper <- function(x, ...)
{
paste(strwrap(x, ...), collapse = "\n")
}
my_title = expression(paste("Here is a really really really looooonnnng title with notation ( ", m^-2,")"))
ggplot(df, aes(x = date, y = value)) +
geom_point() +
labs(x = "",
y = wrapper(my_title, 50)) +
scale_x_date(breaks = seq(st, en, by = "1 month"),
limits = c(st,en),
date_labels = "%b %Y") +
scale_y_continuous(limits = c(0,150),
breaks=seq(0,150,25)) +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16),
axis.text.x = element_text(size = 14, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 14, color = "black"))
You can try to use the package ggtext. If we want to use it, we need to change the normal expression style to HTML and CSS style (which is <sup></sup> for superscript).
For clearer code, I've put your y-axis title into a variable y_lab. The code that is doing the job is theme(axis.title.y = element_textbox_simple(orientation = "left-rotated", halign = 0.5)).
library(ggplot2)
library(ggtext)
y_lab <- "Here is a really really really looooonnnng<br>title with notation (m<sup> -2</sup>)"
ggplot(df, aes(x = date, y = value)) +
geom_point() +
labs(x = "",
y = y_lab)+
scale_x_date(breaks = seq(st, en, by = "1 month"),
limits = c(st,en),
date_labels = "%b %Y") +
scale_y_continuous(limits = c(0,150),
breaks=seq(0,150,25)) +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16),
axis.text.x = element_text(size = 14, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 14, color = "black"),
axis.title.y = element_textbox_simple(orientation = "left-rotated", halign = 0.5))
Related
I am making a time series figure in ggplot2 and would like to set limits for the x-axis. When I try to set the limits using scale_x_datetime(limits = ...), dates beyond the limits are shown, how can I avoid this? I have tried using answers found in similar SO questions (similar 1, similar 2) but have not had success.
Example Data:
library(ggplot2)
library(lubridate)
df <- data.frame(matrix(ncol = 2, nrow = 70176))
colnames(df)[1:2] <- c("DateTime","Value")
df$DateTime <- seq(ymd_hm('2020-01-01 00:00'),ymd_hm('2021-12-31 23:45'), by = '15 mins')
df$Value <- rnorm(70176,100,20)
This attempt comes from the first similar SO question
lims <- as.POSIXct(strptime(c("2020-01-01 00:00","2021-12-31 23:45"), format = "%Y-%m-%d %H:%M"))
ggplot(df, aes(x = DateTime, y = Value)) +
geom_line() +
scale_x_datetime(date_labels = "%b %d %Y",
date_breaks = "1 month",
limits = lims) +
labs(x = "",
y = "Value") +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16, color = "black"),
axis.text.x = element_text(size = 16, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 16, color = 'black'))
This attempt comes from the second similar SO question
ggplot(df, aes(x = DateTime, y = Value)) +
geom_line() +
scale_x_datetime(date_labels = "%b %d %Y",
date_breaks = "1 month",
limits = c(min(df$DateTime), max(df$DateTime))) +
labs(x = "",
y = "Value") +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16, color = "black"),
axis.text.x = element_text(size = 16, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 16, color = 'black'))
The ideal figure would not display dates outside of the limits of the data (i.e., Dec 2019 or Jan 2022).
#JonSpring suggestion of using scale_x_datetime(..., expand = expansion(add = c(0,0))) answered my question. Below is the code using the example dataset for others who might come across this question.
lims <- as.POSIXct(strptime(c("2019-12-15 00:00","2022-01-15 23:45"), format = "%Y-%m-%d %H:%M"))
ggplot(df, aes(x = DateTime, y = Value)) +
geom_line() +
scale_x_datetime(date_labels = "%b %d %Y",
date_breaks = "1 month",
limits = lims,
expand = expansion(add = c(0,0))) +
labs(x = "",
y = "Value") +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16, color = "black"),
axis.text.x = element_text(size = 16, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 16, color = 'black'))
Using expand = c(0,0) in scale_x_datetime() will remove extra space.
I cannot get geom_boxplot to display a time series from oldest date to newest date.
Example Data:
set.seed(321)
dat <- data.frame(matrix(ncol = 3, nrow = 216))
colnames(dat)[1:3] <- c("Date","Location","Value")
dat$Value <- round(rnorm(216, 100,75),0)
dat$Location <- rep(c("Location 1","Location 2"), each = 108)
st <- as.Date("2020-01-01")
en <- as.Date("2022-12-31")
dat$Date <- rep(seq.Date(st,en,by = '1 month'),6)
str(dat)
This plot has the x-axis sorted based on the alphabetical order of the month, then year (i.e., Apr 2020, Apr 2021, Apr 2022, Aug 2020, etc).
ggplot(dat, aes(x = format(Date, "%b %Y"), y = Value, fill = Location, group = interaction(Date, Location))) +
geom_boxplot() +
labs(x = "") +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16),
axis.text.x = element_text(size = 14, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 14, color = "black"))
How can I get the x-axis to display in chronological order (i.e., Jan 2020, Feb 2020, etc.)?
We could do it this way:
library(ggplot2)
ggplot(dat, aes(x = Date, y = Value, fill = Location, group = interaction(Date, Location))) +
geom_boxplot() +
labs(x = "") +
scale_x_date(date_breaks = "1 month",
date_labels = "%b %Y") +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16),
axis.text.x = element_text(size = 14, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 14, color = "black"))
For ggplot2 to arrange your data by Date, it's simplest to preserve the x axis data as Date data (which ggplot2 knows how to display on a timeline) instead of as formatted text (which ggplot2 doesn't assign any semantic meaning to -- "Jan 2020" is no different from "Apple"). You can adjust the label formatting with scale_x_date(date_labels = ...)
(It's also possible to sort text values by converting them to "factors," which have the option of being ordered, but then you would lose the relationship to the timeline; gaps in time would not be shown with gaps, for instance.)
library(ggplot2)
ggplot(dat, aes(x = Date, y = Value, fill = Location, group = interaction(Date, Location))) +
geom_boxplot() +
scale_x_date(date_labels = "%b %Y") +
labs(x = "") +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16),
axis.text.x = element_text(size = 14, color = "black", angle = 90, vjust = 0.5, hjust = 1),
axis.text.y = element_text(size = 14, color = "black"))
p <- ggplot(data = JRdata, aes(x = reorder(tag,+occlusion19), y = occlusion19,
fill = IndividualSelectionMetagenomics,
colour = IndividualSelectionMetagenomics)) +
geom_bar(stat = "identity") +
scale_fill_manual(values = c("white","red")) +
scale_colour_manual(values = c("black", "black")) +
geom_col() +
geom_text_repel(aes(label=ifelse(IndividualSelectionMetagenomics=="Y",paste0(tag),"")),
angle = 90, size = 10, nudge_y = 1) +
theme_bw() + labs(x = "ID number", y = "Portion of Stomata Occluded /10") +
theme(axis.title.x = element_text(size = 40), axis.title.y = element_text(size = 40)) +
theme(legend.text = element_text(size = 20)) +
theme(legend.title = element_text(size = 40)) +
theme(legend.position = c(.95, .95), legend.justification = c("right", "top")) +
theme(element_blank()) +
theme(axis.text.x = element_blank()) +
ggsave(plot = p, width = 40, height = 20, dpi = 300, limitsize = FALSE, filename = "not squished axis.pdf")
How to avoid overlapping the lagend labels in ggplot?
ggplot(g3, aes(variable, country, fill= value)) + geom_tile() +
theme(axis.text.y = element_text(size = 15), axis.text.x = element_text(angle = 45, hjust = 1, size = 15), legend.position="bottom", legend.text = element_text(size = 15, angle = 50),
axis.title.x = element_blank(),axis.title.y = element_blank())
For axis labels, the best way to fix this is to use the ggplot2::guide_axis() function, which will adjust both the angle and vertical/horizontal positioning at the same time. You can also make your legend labels easier to read by scaling the label. This might obviate the need to rotate the legend labels. For example:
library(ggplot2)
ggplot(g3, aes(variable, country, fill = value)) +
geom_tile() +
labs(x = "", y = "") +
scale_fill_continuous(labels = scales::label_number(scale = 10000, suffix = "k")) +
guides(x = guide_axis(angle = 45), fill = guide_colorbar(direction = "horizontal)) +
theme(legend.position = "bottom", text = element_text(size = 15))
I am developing a Taipan Chart that would show date variations to different items.
I got completely stuck to sort out the data by the Reporting date order to have the line ( geom_path() ) connecting the points in that order.
I was trying to sort it as you can see in the code. However, nothing is happening.
Could you please help me with this issue? Data Link .csv : https://drive.google.com/file/d/1MUJn4zPNIkZu1bEq_qNdConVLsDeebzv/view
library(ggplot2)
library(scales)
x <- as.Date(dataset$"Due Date", "%Y-%m-%d")
y <- as.Date(dataset$"Reporting Date", "%Y-%m-%d")
Item <- dataset$"Key Work Activity / Milestone"
ggplot(dataset[order(dataset$"Reporting Date"),], aes (x,y,colour = factor(Item))) +
geom_path(size = 1) +
labs( x = "Forecast Date", y = "Reporting Date") +
theme(
legend.position = "bottom",
panel.background = element_rect(fill=NA, colour = NA),
panel.grid.major = element_line (size = 0.1, linetype = "solid", colour = "black")
)+
geom_point(size=3) +
geom_hline(yintercept = Sys.Date(), linetype = "dashed" , colour ="blue") +
geom_vline(xintercept = Sys.Date(), linetype = "dashed", colour = "blue") +
scale_x_date(date_labels = "%b %Y", date_breaks = "1 month") +
theme(axis.text.x = element_text(angle = 45)) +
scale_y_date(date_labels = "%b %Y", date_breaks = "1 month") +
theme(axis.text.y = element_text(angle = 45))
This is what I am trying to achieve
This is what I have now