Changing Format of Some Axis Labels in Ggplot2 According to Condition

Changing format of some axis labels in ggplot2 according to condition

You can include for example ifelse() function inside element_text() to have different labels.

ggplot(iris,aes(Species,Petal.Length))+geom_boxplot()+
theme(axis.text.x=
element_text(face=ifelse(levels(iris$Species)=="setosa","bold","italic")))

Or you can provide vector of values inside element_text() the same length as number of levels.

ggplot(iris,aes(Species,Petal.Length))+geom_boxplot()+
theme(axis.text.x = element_text(face=c("bold","italic","bold"),
size=c(11,12,13)))

Sample Image

Dynamically formatting individual axis labels in ggplot2

How about

breaks <- levels(data$labs)
labels <- as.expression(breaks)
labels[[2]] <- bquote(bold(.(labels[[2]])))

ggplot(data = data) +
geom_bar(aes(x = labs, y = counts), stat="identity") +
scale_x_discrete(label = labels, breaks = breaks)

Here we are more explicit about the conversion to expression and we use bquote() to insert the value of the label into the expression itself.

Conditional formatting of axis text using ggplot2

Your con variable has five elements, the first three of which are "red":

[1] "red"   "red"   "red"   "green" "green"

Since there are only three axis labels, theme uses the first three values, thus making all labels red. When con is of the proper length, we get the desired result:

con <- ifelse(unique(df$variable) == 'a', 'red', 'darkgreen')

Sample Image

Conditional change of axis.text font family and font size creates unwanted 'gap'

The problem is fixed in the upcoming ggplot2 3.3.0, but it now triggers a warning, because this approach of formatting axis text is not reliable and could stop working at any point in the future.

library(ggplot2) # v 3.3.0 or higher

# discouraged, triggers warning message
ggplot(iris, aes(Species, Petal.Length)) +
geom_boxplot() + coord_flip() +
theme(
axis.text.y = element_text(
size = ifelse(levels(iris$Species)=="setosa", 10, 20)
)
)
#> Warning: Vectorized input to `element_text()` is not officially supported.
#> Results may be unexpected or may change in future versions of ggplot2.

Sample Image

As an alternative, the ggtext package under development attempts to provide a principle approach to this problem, by encoding the formatting instructions into the text labels.

library(ggtext) # remotes::install_github("clauswilke/ggtext")
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(glue)
#>
#> Attaching package: 'glue'
#> The following object is masked from 'package:dplyr':
#>
#> collapse

iris %>%
mutate(
Species = ifelse(
Species == "setosa",
"<span style = 'font-size:10pt'>setosa</span>",
glue("<span style = 'font-size:20pt'>{Species}</span>")
)
) %>%
ggplot(aes(Species, Petal.Length)) +
geom_boxplot() + coord_flip() +
theme(axis.text.y = element_markdown())

Sample Image

Created on 2020-01-16 by the reprex package (v0.3.0)

customize ggplot2 axis labels with different colors

You can provide a vector of colors to the axis.text.x option of theme():

a <- ifelse(data$category == 0, "red", "blue")

ggplot(data, aes(x = x, y = y)) +
geom_bar(stat = "identity", aes(fill = category)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, colour = a))

Sample Image

ggplot2: Conditional formatting of x axis label in facet_grid

Well, as the warning tells you it is not recommended to choose the axis text colours by using vectorised theme input (although many people try nonetheless). I believe this was also one of the motivations behind the ggtext package, in which you can use markdown to stylise your text. Below, you'll find an example with a standard dataset, I hope it translates well to yours. We just conditionally apply colouring to some of the x-axis categories.

library(ggplot2)
library(ggtext)
#> Warning: package 'ggtext' was built under R version 4.0.3

df <- transform(mtcars, car = rownames(mtcars))[1:10,]

red_cars <- sample(df$car, 5)

df$car <- ifelse(
df$car %in% red_cars,
paste0("<span style='color:#FF0000'>", df$car, "</span>"),
df$car
)

ggplot(df, aes(car, mpg)) +
geom_col() +
theme(axis.text.x = element_markdown(angle = 90))

Sample Image

Created on 2021-02-03 by the reprex package (v1.0.0)

For more examples, see https://github.com/wilkelab/ggtext#markdown-in-theme-elements

How do you specifically order ggplot2 x axis instead of alphabetical order?

It is a little difficult to answer your specific question without a full, reproducible example. However something like this should work:

#Turn your 'treatment' column into a character vector
data$Treatment <- as.character(data$Treatment)
#Then turn it back into a factor with the levels in the correct order
data$Treatment <- factor(data$Treatment, levels=unique(data$Treatment))

In this example, the order of the factor will be the same as in the data.csv file.

If you prefer a different order, you can order them by hand:

data$Treatment <- factor(data$Treatment, levels=c("Y", "X", "Z"))

However this is dangerous if you have a lot of levels: if you get any of them wrong, that will cause problems.

How to customize ggplot2 axis labels with different colors when values are continuous

The following will work for ggplot2 3.0.0. For earlier versions of ggplot2, the exact structure of ggplot_build(plt1)$layout$panel_params[[1]]$y.label will vary.


In the reproducible dataset and corresponding chart below, you'll se that both columns A and B in the dataframe df have 10 observations, and that B displayed on the y-axis is assigned with 4 labels. Using the ggplot_build() and theme() you can reference and format the y labels any way you like. Below, negative and positive numbers are assigned the colors red and blue, respectively. Zero remains black.

Snippet

# settings
library(ggplot2)
set.seed(123)

# data
A = rnorm(10, mean=0, sd=1)
B = rnorm(10, mean=0, sd=1)
df <- data.frame(A,B)

# initial plot
plt1 <- ggplot(data = df) + aes(x=A, y=B)+geom_line()

# retrieve lables using ggplot_build()
yLabVals <- as.numeric(ggplot_build(plt1)$layout$panel_params[[1]]$y.labels)

# create color list
yLabs <- ifelse(yLabVals < 0, "red", "blue")
yLabs[yLabVals == 0] <- 'black'

# plot
plt2 <- plt1 + theme(axis.text.y = element_text(angle = 0, hjust = 1, colour = yLabs))
plt2

Plot

Sample Image

Make every Nth axis label bold with ggplot2

You can try:

ggplot(df, aes(x=date, y=value, color=variable)) + 
geom_line() +
scale_color_manual(values = c("#00ba38", "#f8766d")) +
scale_x_date(date_breaks = "1 year", date_labels ="%Y") +
theme(axis.ticks.x = element_line(colour = "black", size = c(5, rep(1,5))),
axis.text.x = element_text(angle = 90, vjust=0.5, size = c(15,rep(8,5))))

Sample Image

used every 6th and text size for illustration purposes.
You can also use your breaks and labels but then you have to use following instead as you duplicated all breaks and labels and they must priorly removed.

scale_x_date(labels = lbls[!duplicated(lbls)], breaks = brks[!duplicated(lbls)]) 


Related Topics



Leave a reply



Submit