Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Justify individual axis labels in bold using ggplot2

Question adapted from this question and solution: Highlighting individual axis labels in bold using ggplot2

I would like to selectively justify the horizontal axes labels depending on meeting a criteria. So borrowing from the above question and answer I've set up an example:

require(ggplot2)
require(dplyr)
set.seed(36)
xx<-data.frame(YEAR=rep(c("X", "Y"), each=20),
           CLONE=rep(c("A", "B", "C", "D", "E"), each=4, 2),
           TREAT=rep(c("T1", "T2", "T3", "C"), 10),
           VALUE=sample(c(1:10), 40, replace=T))

# Simple plot with factors on y axis
ggplot(xx, aes(x = VALUE, y=CLONE, fill=YEAR)) + 
    geom_bar(stat="identity", position="dodge") +
    facet_wrap(~TREAT)

enter image description here

Ok so I adopted function from the above question + answer to generate a vector of justifications:

# Modify to control justification
colorado2 <- function(src, boulder) {
    if (!is.factor(src)) src <- factor(src)                   
    src_levels <- levels(src)                                 
    brave <- boulder %in% src_levels                         
    if (all(brave)) {                                         
        b_pos <- purrr::map_int(boulder, ~which(.==src_levels)) 
        b_vec <- rep(0.2, length(src_levels))               
        b_vec[b_pos] <- 0.9                                 
        b_vec                                                  
    } else {
        stop("All elements of 'boulder' must be in src")
    }
}

# Redraw the plot with modifcation
ggplot(xx, aes(x = VALUE, y=CLONE, fill=YEAR)) + 
    geom_bar(stat="identity", position="dodge") +
    facet_wrap(~TREAT) +
    theme(axis.text.y=element_text(hjust=colorado2(xx$CLONE, c("A", "B", "E"))))

I'm getting this unfortunate mess: enter image description here

The labels are justified in the direction I want - but taking up far too much of the plot for reasons I cannot figure out. How do I fix this ?

like image 897
user2498193 Avatar asked Jan 16 '18 16:01

user2498193


People also ask

How do I make my Axis bold in ggplot2?

text argument to make both x and y-axis text bold using element_text() function. We can make the axis text font bold by using face=”bold” argument to element_text() function. Note now the both x and y-axis text are in bold font and more clearly visible than the default axis text.

How do I make axis labels bold in R?

Make Axis Title Text Bold Font with element_text() To make both x and y-axis's title text in bold font, we will use axis. title argument to theme() function with element_text(face=”bold”). Note now both x and y axis's title text are in bold font.

How do I make my axis labels bigger in ggplot2?

To increase the X-axis labels font size using ggplot2, we can use axis. text. x argument of theme function where we can define the text size for axis element. This might be required when we want viewers to critically examine the X-axis labels and especially in situations when we change the scale for X-axis.

How do I rename the y axis in R?

The easiest way to change the Y-axis title in base R plot is by using the ylab argument where we can simply type in the title. But the use of ylab does not help us to make changes in the axis title hence it is better to use mtext function, using which we can change the font size, position etc.

How to add bold text to a ggplot2 plot using GGP?

For this, we have to specify the fontface argument within the annotate function to be equal to “bold”: ggp + # Add bold text element to plot annotate ("text", x = 4.5, y = 2.2, size = 5 , label = "My Bold Text" , fontface = "bold") As you can see in Figure 2, we have created a ggplot2 plot containing a bold text element with the previous code.

How to modify axis labels using Ggplot2 bar plot in R?

In this article, we are going to see how to modify the axis labels, legend, and plot labels using ggplot2 bar plot in R programming language. For creating a simple bar plot we will use the function geom_bar ( ). stat : Set the stat parameter to identify the mode. fill : Represents color inside the bars.

How to change axis labels and main titles in a plot?

Axis labels and main titles can be changed to reflect the desired appearance. For this element_text () function is passed with the required attributes. For this theme () function is called with reference to which part of the plot has to be modified. To these references, pass element_blank () without any argument.

How do I add cursive text elements to a ggplot2 graph?

Example 2 illustrates how to add cursive text elements to a ggplot2 graph by specifying the fontface argument to be equal to “italic”: ggp + # Add italic text element to plot annotate ("text", x = 4.5, y = 2.2, size = 5 , label = "My Italic Text" , fontface = "italic")


1 Answers

I did some digging. The problem is with how ggplot sets the grob width of the y axis grob. It assumes that hjust is the same across all labels. We can fix this with some hacking of the grob tree. The following code was tested with the development version of ggplot2 and may not work as written with the currently released version.

First, a simple reproducible example:

p <- ggplot(mpg, aes(manufacturer, hwy)) + geom_boxplot() + coord_flip() + 
  theme(axis.text.y = element_text(hjust = c(rep(1, 10), rep(0, 5))))
p # doesn't work

enter image description here

The problem is that the grob width of the axis grob gets set to the entire plot area. But we can manually go in and fix the width. Unfortunately we have to fix it in multiple locations:

# get a vector of the y labels as strings
ylabels <- as.character(unique(mpg$manufacturer))

library(grid)
g <- ggplotGrob(p)

# we need to fix the grob widths at various locations in the grob tree
g$grobs[[3]]$children[[2]]$widths[1] <- max(stringWidth(ylabels))
g$grobs[[3]]$width <- sum(grobWidth(g$grobs[[3]]$children[[1]]), grobWidth(g$grobs[[3]]$children[[2]]))
g$widths[3] <- g$grobs[[3]]$width

# draw the plot
grid.newpage()
grid.draw(g)

enter image description here

The axis-drawing code of ggplot2 could probably be modified to calculate width like I did here from the outset, and then the problem would disappear.

like image 170
Claus Wilke Avatar answered Oct 25 '22 05:10

Claus Wilke