I am using the R package GGPubr to make Boxplots. I really like the nice visuals that it provides but am having problems. Does anyone know how to increase the font size of the numbers on the axes, and the axis labels, and class labels? Also how do I set the mean values so that they only display 2 decimal places?
Here is the code that I'm using:
library("ggpubr")
mydata <- read.csv("C:\\temp\\ndvi.csv")
ggboxplot(mydata, x = "class", y = "NDVI",
color = "class",
order = c("Conifer", "Deciduous", "Grasslands"), ggtheme=theme_gray(),
ylab = "NDVI Value", xlab = "Land Cover Class",
add="mean",
font.label = list(size = 30, face = "bold"))+ stat_summary(fun.data
= function(x) data.frame(y=1, label = paste("Mean=",mean(x))), geom="text")
+theme(legend.position="none")
And the csv:
NDVI,class
0.25,Conifer
0.27,Conifer
0.29,Conifer
0.403,Deciduous
0.38,Deciduous
0.365,Deciduous
0.31983489,Grasslands
0.32005,Grasslands
0.328887766,Grasslands
I would prefer to achieve the desired effects above with GGPubr rather than boxplot() or ggplot/ggplot 2. Thanks.
Here is one option where we use round() to take care of the two decimal places and add another theme() to change the text size.
ggboxplot(mydata, x = "class", y = "NDVI",
color = "class",
order = c("Conifer", "Deciduous", "Grasslands"), ggtheme=theme_gray(),
ylab = "NDVI Value", xlab = "Land Cover Class",
add="mean",
font.label = list(size = 30, face = "bold")) +
# use round() and set y = .45
stat_summary(fun.data = function(x) data.frame(y=1, label = paste("Mean=", round(mean(x), 2))), geom="text") +
theme(legend.position="none") +
theme(text = element_text(size = 16)) # change text size of theme components
Related
The scale does not change the way I want and the way I wrote in the code. Why is that? Can someone help? My goal is to have a tick and label for every year on the x axis and a scale from -6 to 3 on the y axis, also including ticks and labels.
Periode <- as.Date(website$Datum)
Index <- website$KonSens
datebreaks <- seq(as.Date("1998-03-31"), as.Date("2022-06-30"), by = "1 month")
plot.Website <-
ggplot(data = website, aes(x = Periode, y = Index)) +
scale_x_date(breaks = datebreaks) +
scale_y_continuous(breaks = seq(-6,3,1), labels = c("-6", "-5", "-4", "-3", "-2", "-1", "0", "1", "2", "3"), limits = c(-6,4), n.breaks = 10)+
theme(axis.text = element_text(color = "black", face = "bold", size = 10),
axis.line.y = element_line(color = "black", size = 2),
axis.line.x = element_blank(),
axis.title = element_text(color = "black", face = "bold"),
axis.title.y = element_text(angle = 180)) +
geom_line(aes(y = Index), color = "#7AA489",size = 1.5) +
geom_point(shape = 21, color = "#003478", fill = "#7AA489", size = 2.5, stroke = 1)
ggplotly(plot.Website, dynamicTicks = TRUE) %>%
rangeslider(borderwidth = 1)
Plotly may ignore you regardless of what you do because it looks like you are asking for almost 300 tick labels on the x-axis. However, when you use ggplotly, date fields become character fields. (I don't know if this is from ggplot or if it's a Plotly-ism.)
After rendering the ggplotly object, you can replace the x in each trace and replace the majority of the arguments for layout.xaxis. Alternatively, you may find it to be a lot easier if you create this in Plotly, to begin with.
I've added the data I used because your question is not reproducible. It looks like you're new to SO; welcome to the community! If you want great answers quickly, it's best to make all questions reproducible. For example, sample data from the output of dput() or reprex::reprex(). Check it out: making R reproducible questions.
In the following code, the only parts you need to create the plot without the aesthetics are the first two piped: plot_ly() and add_lines().
I added comments to explain what different aspects of this code is doing. Additionally, I've broken down some of this a bit further after the code and plot image.
library(tidyverse)
library(plotly)
# Periode <- as.Date(website$Datum) # data not provided
# Index <- website$KonSens
set.seed(353)
website <- data.frame(
Periode = sample(seq(as.Date("1998-03-31"), as.Date("2022-06-30"), by = "week"), 50),
Index = sample(runif(100, -4.5, 2.5), 50)) %>%
arrange(Periode)
plot_ly(type = "scatter", mode = "markers",
marker = list(color = "#7AA489", size = 8,
line = list(width = 2, color = "#003478")),
data = website, x = ~Periode, y = ~Index) %>%
add_lines(line = list(width = 5, color = "#7AA489")) %>%
layout(xaxis = list(dtick = "M18", # every 18 months
tickformat = "%b %Y"), # Abbrev Month, 4-digit year
yaxis = list(range = c(-6, 3), # show this range
zeroline = F, # remove horizontal line at 0
showline = T), # vertical line along y-axis
showlegend = F) %>% # no legend
htmlwidgets::onRender("function(el, x){. # make the axis titles BOLD
gimmeX = document.querySelector('g.infolayer g.g-xtitle text');
gimmeY = document.querySelector('g.infolayer g.g-ytitle text');
gimmeX.style.fontWeight = 'bold';
gimmeY.style.fontWeight = 'bold';
}") %>%
rangeslider(borderwidth = 1)
Specifying the Range on the y-axis
In Plotly, you won't need to set breaks and labels. You just need to define the range. If that's all you designated in the layout, it would like something like this.
layout(yaxis = list(range = c(-6, 3))
Non-Dynamic Date x-axis Tick Text Formatting
Labels on the x-axis can be specified to be labeled by month. However, like a commenter mentioned, you loose the dynamic date scaling done when you zoom. You can actually set the scaling date format for zooming ranges, as well. (I won't go into that in this answer, though.)
To specify the labels on the x-axis as every month by month, you would use layout.xaxis.dtick = "M1", every 18 months is M18, and so on. If you wanted to specify the appearance as the month and year, you can use the same formatting as used in as.Date, where %b is an abbreviated month name, and %Y is a four-digit year. If this was all you needed to set in the layout, it would look like this.
layout(xaxis = list(dtick = "M18", # every 18 months
tickformat = "%b %Y")) # Abbrev Month, 4-digit year
Bold Axis Labels
Additionally, there isn't a parameter you can set to make the axis labels bold. It doesn't really matter if it's ggplotly or plot_ly.
However, you can use htmlwidgets::onRender to make this happen.
htmlwidgets::onRender("function(el, x){
gimmeX = document.querySelector('g.infolayer g.g-xtitle text');
gimmeY = document.querySelector('g.infolayer g.g-ytitle text');
gimmeX.style.fontWeight = 'bold';
gimmeY.style.fontWeight = 'bold';
}")
This solution https://stackoverflow.com/a/71590169/7106842
is effective a changing the font of the title, x-axis, and y-axis labels. But not of the annotated data labels. They are still default font. Is there a way to change those labels as well?
I recognize this isn't a minimally reproducible example but the code below was the original partial solution to the problem.
#incorrect model with labels added by sjPlot
a = (plot_model(sl_distr_model,
order.terms = c(1,2,3,4,5,6,7),
show.values = TRUE,
value.offset = .3,
rm.terms = c("taxon_detailAnas platyrhynchos","taxon_detailAnas strepera","logshape","logshape:cadencefactor1h","logshape:cadencefactor2h","logshape:cadencefactor3h","logshape:cadencefactor6h","logshape:cadencefactor12h","logshape:cadencefactor24h"),
axis.lim = c(xlimrange_min,xlimrange_max),
colors = c("firebrick"),
wrap.labels = 60,
title = c("Plot 3: Intercept parameters by time interval - Relationship bewtween shape and scale gamma parameters of step length distributions 7.429"),
axis.title = "Intercept = Red; Ratio of Shape to Rate parameters = Blue"))
#added 2 fonts I had installed
windowsFonts(A = windowsFont("Times New Roman"), B = windowsFont("Century Gothic"))
#incomplete formating
a + theme(text = element_text(family = "A")
The above code did not change the data label font. The all components of the chart were Times New Roman except for the data labels which remained the system deault (courier), to fix this I had to manually add the relevant values using geom_text() referencing the same font family as the rest of the chart
#correct model without data labels
aa = (plot_model(sl_distr_model,
order.terms = c(1,2,3,4,5,6,7),
show.values = FALSE,
value.offset = .3,
rm.terms = c("taxon_detailAnas platyrhynchos","taxon_detailAnas strepera","logshape","logshape:cadencefactor1h","logshape:cadencefactor2h","logshape:cadencefactor3h","logshape:cadencefactor6h","logshape:cadencefactor12h","logshape:cadencefactor24h"),
axis.lim = c(xlimrange_min,xlimrange_max),
colors = c("firebrick"),
wrap.labels = 60,
title = c("Plot 3: Intercept parameters by time interval - Relationship bewtween shape and scale gamma parameters of step length distributions 7.429"),
axis.title = "Intercept = Red; Ratio of Shape to Rate parameters = Blue"))
aa + theme(text = element_text(family = "B")) + geom_text(aes(label= round(sl_distr_model#beta[2:8],2)), family = "B", nudge_x = 0.25, check_overlap = F)
Now all text is Century Gothic.
I'm trying to wrangle a Volcano plot made with the EnhancedVolcano package to have all text in Arial font style. I tried to do so with this code:
a <- EnhancedVolcano(data.matrix,
lab = rownames(data.matrix), x = "Log2.fold.change",
y = "P.value", xlim = c(-2, 2), ylim = c(0, 6), xlab = bquote(~ Log[2] ~ "fold change"),
ylab = bquote(~ -Log[10] ~ italic(P)), axisLabSize = 12,
title = paste("NanoString -", data.name), subtitle = "",
labFace = "bold", pointSize = 2, labSize = 5, pCutoff = 10e-2, FCcutoff = 0.4,
gridlines.major = FALSE, gridlines.minor = FALSE, drawConnectors = TRUE,
widthConnectors = 0.2, colConnectors = "black", legendPosition = "none"
)
print(a)
EV_merge <- a + theme(text = element_text(size = 8, family = "sans"))
print(EV_merge)
The problem I'm having is the element_text command, which I thought would work since the plot is an object in ggplot2, seems to only work for the axis and title text, but the font of the labels for the specific genes seems to remain the same. What function should I be using in this case?
The labels are nothing to do with theme. They are created by geom_text_repel, so they are part of a data layer. There doesn't seem to be an option to change the font family of the labels, but you can change it in situ after the plot is created.
Obviously, I don't have your data, but using the example from the help page and saving it as EV_merge, we have:
EV_merge
To change the font face and family, we can do:
EV_merge$layers[[4]]$aes_params$fontface <- 1
EV_merge$layers[[4]]$aes_params$family <- "sans"
EV_merge
I am trying to customize a plot for competing risks using R and the package cmprsk. Specifically, I want to overwrite the default that for competing events colors are used and for different groups linetypes are used.
Here is my reproducible example:
library(ggplot2)
library(cmprsk)
library(survminer)
# some simulated data to get started
comp.risk.data <- data.frame("tfs.days" = rweibull(n = 100, shape = 1, scale = 1)*100,
"status.tfs" = c(sample(c(0,1,1,1,1,2), size=50, replace=T)),
"Typing" = sample(c("A","B","C","D"), size=50, replace=T))
# fitting a competing risks model
CR <- cuminc(ftime = comp.risk.data$tfs.days,
fstatus = comp.risk.data$status.tfs,
cencode = 0,
group = comp.risk.data$Typing)
# the default plot makes it impossible to identify the groups
ggcompetingrisks(fit = CR, multiple_panels = F, xlab = "Days", ylab = "Cumulative incidence of event",title = "Competing Risks Analysis")+
scale_color_manual(name="", values=c("blue","red"), labels=c("Tumor", "Death without tumor"))
Using ggplot_build() I managed to change the default regarding linetype and color, but I cannot find a way to add a legend.
p2 <- ggcompetingrisks(fit = CR, multiple_panels = FALSE, xlab = "Days", ylab = "Cumulative incidence of event",title = "Death by TCR", ylim = c(0, 1)) +
scale_color_manual(name="", values=c("blue","red"), labels=c("Tumor", "Death without tumor"))
q <- ggplot_build(p2)
q$data[[1]]$colour2 <- ifelse(q$data[[1]]$linetype=="solid","blue", ifelse(q$data[[1]]$linetype==22,"red", ifelse(q$data[[1]]$linetype==42,"green", ifelse(q$data[[1]]$linetype==44,"black", NA))))
q$data[[1]]$linetype <- ifelse(q$data[[1]]$colour=="blue","solid", ifelse(q$data[[1]]$colour=="red","dashed", NA))
q$data[[1]]$colour <- q$data[[1]]$colour2
q$plot <- q$plot + ggtitle("Competing Risks Analysis") + guides(col = guide_legend()) + theme(legend.position = "right")
p2 <- ggplot_gtable(q)
plot(p2)
Does anyone know how to add the legend to a plot manipulated by ggplot_build()? Or an alternative way to plot the competing risks such that color indicated group and linetype indicates event?
You don't need to go down the ggplot_build route. The function ggcompetingrisks returns a ggplot object, which itself contains the aesthetic mappings. You can overwrite these with aes:
p <- ggcompetingrisks(fit = CR,
multiple_panels = F,
xlab = "Days",
ylab = "Cumulative incidence of event",
title = "Competing Risks Analysis")
p$mapping <- aes(x = time, y = est, colour = group, linetype = event)
Now we have reversed the linetype and color aesthetic mappings, we just need to swap the legend labels and we're good to go:
p + labs(linetype = "event", colour = "group")
Note that you can also add color scales, themes, coordinate transforms to p like any other ggplot object.
I have this code:
tm_shape(usa, bbox = bbox, projection = map.crs)+
tm_borders(col = "grey", lwd = 1) +
tm_fill(palette = "grey") +
tm_grid(x = c(-77,-75,-73,-71),
y = c(39,37,35),
labels.inside.frame = F,
labels.size = 1.1,
col = "white") +
tm_layout(outer.margins = c(.1,.03,.05,.05),
outer.bg.color = "white")+
tm_shape(sk.dat1,axes = T) +
tm_dots("DATELAND", palette = colo,
auto.palette.mapping=FALSE,
size = .5,
breaks = seq(2010,2017,
length.out =8),legend.show = T, alpha=.7) +
tm_layout(title = "Southern Kingfish Occurrence",
legend.show = T,
legend.position = c("right","bottom"),
legend.bg.color = "grey70",
legend.height = 2)
Which outputs this legend. How can I change the tmap input to only include single years with no commas?
This looks as a number format problem; your code is not exactly reproducible, so I can not make 100% sure, but I am fairly certain by the look.
To remedy try including this in your tm_layout call:
legend.format=list(fun=function(x) formatC(x, digits=0, format="d"))
By the way I wrote a short blog post on tmap legend formatting a couple months back (my problem were currency and percentage signs).
https://www.jla-data.net/eng/tmap-legend/