I'm trying to put expressions into facet labels using label_parsed but with no success:
library(ggplot2)
mpg3 <- mpg
levels(mpg3$drv)[levels(mpg3$drv)=="4"] <- "4^{wd}"
levels(mpg3$drv)[levels(mpg3$drv)=="f"] <- "- Front %.% e^{pi * i}"
levels(mpg3$drv)[levels(mpg3$drv)=="r"] <- "4^{wd} - Front"
ggplot(mpg3, aes(x=displ, y=hwy)) + geom_point() +
facet_grid(. ~ drv, labeller = label_parsed)
The plot that I get lacks expressions - facet labels contain the original levels of drv variable.
If I type levels(mpg3$drv) I get character(0).
There are two problems - firstly mpg$drv is character, not factor, and secondly, you need to set the factor labels, not the levels. I think this is what you want...
mpg3 <- mpg
mpg3$drv <- factor(mpg3$drv,
levels=c("4","f","r"),
labels=c("4^{wd}","- Front %.% e^{pi * i}","4^{wd} - Front"))
ggplot(mpg3, aes(x=displ, y=hwy)) +
geom_point() +
facet_grid(. ~ drv, labeller = label_parsed)
Related
From ggplot2's reference manual, of label_both:
library(ggplot2)
mtcars$cyl2 <- factor(mtcars$cyl, labels = c("alpha", "beta", "gamma"))
p <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
# Displaying both the values and the variables
p + facet_grid(. ~ cyl, labeller = label_both)
This will give us facet strips with both variable name and its values. However, say if I want to change the appearance of the variable name, but not change the values, e.g.:
expression(italic(cyl))
So that I can get a cyl: 4 instead of cyl: 4, is it possible to do it using the labeller function?
After a look at the docs and the source code label_both has no parse option. But similar to the approach in the answer referenced by #jared_mamrot in his comment you could use as_labeller to create a custom labeller for which you use label_parsed.
library(ggplot2)
mtcars$cyl2 <- factor(mtcars$cyl, labels = c("alpha", "beta", "gamma"))
p <- ggplot(mtcars, aes(wt, mpg)) +
geom_point()
p + facet_grid(. ~ cyl,
labeller = as_labeller(
~ paste0("italic(cyl):", .x), label_parsed
)
)
In my ggplot below, I'm trying to change the 10 facet labels of facet_wrap using labeller(sch.id=paste0("sch.id:", unique(ten$sch.id))).
However, the plot shows NA instead of the correct facet labels, I wonder what the fix is?
library(ggplot2)
hsb <- read.csv('https://raw.githubusercontent.com/rnorouzian/e/master/hsb.csv')
ten <- subset(hsb, sch.id %in% unique(sch.id)[1:10])
p <- ten %>% ggplot() + aes(ses, math) + geom_point() +
facet_wrap(~sch.id) + geom_smooth(method = "lm", se = FALSE)
p + facet_wrap(~sch.id, labeller = labeller(sch.id=paste0("sch.id:", unique(ten$sch.id)))) ## HERE ##
The problem seems to be that you are passing a variable to the labeller function but facet_wrap already passes its own faceting variable. A conflict occurs and the result are NA's.
The solution is to create a labeller function as a function of a variable x (or any other name as long as it's not the faceting variables' names) and then coerce to labeller with as_labeller.
Note that there is no need for unique, just like there is no need for it in the facet_wrap formula.
p <- ten %>% ggplot() + aes(ses, math) + geom_point() +
geom_smooth(method = "lm", formula = y ~ x, se = FALSE)
cust_labeller <- function(x) paste0("sch.id:", x)
p + facet_wrap(~ sch.id,
labeller = as_labeller(cust_labeller)) ## HERE ##
I think the easiest way would be to change sch.id before plotting.
library(ggplot2)
ten$sch.id <- paste0("sch.id:", ten$sch.id)
ggplot(ten) + aes(ses, math) +
geom_point() +
geom_smooth(method = "lm", se = FALSE) +
facet_wrap(~sch.id)
If you don't want to modify your data and want to use the labeller argument you can create a named vector and use it in labeller.
cust_label <- setNames(paste0("sch.id:", unique(ten$sch.id)), unique(ten$sch.id))
ggplot(ten) + aes(ses, math) +
geom_point() +
geom_smooth(method = "lm", se = FALSE) +
facet_wrap(~sch.id, labeller = as_labeller(cust_label))
I want to add label with mathematical expressions in two line with facet_grid for two grids (See MWE). I can get that in one line, wonder to get in two lines (Beta in one line and Gamma in second line in second graph).
library(ggplot2)
p1 <- ggplot(mtcars, aes(x = mpg, y = wt)) + geom_point()
p1 + facet_grid(
facets = gear ~ vs + am
, labeller = label_both
)
p1 + facet_grid(
facets = gear ~ vs + am
, labeller =
label_bquote(
rows = alpha:.(gear)
, cols = list(beta:.(vs), gamma:.(am))
)
)
You can use atop() instead of list():
library(ggplot2)
ggplot(mtcars, aes(mpg, wt)) +
geom_point() +
facet_grid(gear ~ vs + am,
labeller = label_bquote(
rows = alpha:.(gear),
cols = atop(beta:.(vs), gamma:.(am))))
atop() is a brute force approach as it puts "x over y (no horizontal bar)"
I have a long list of column names that I want to use it in the facet_grid. I would like to select some column names and put + as facet_grid function require.
I have tried this with mtcars but couldn't figure it out why unlist or paste are not working.
names=paste(unlist(names(mtcars)[c(1,3,5)]),sep='+')
library(ggplot2)
ggplot(mtcars, aes("", hp)) +
geom_boxplot(width=0.7, position=position_dodge(0.7)) +
theme_bw() +
facet_grid(. ~ names,switch = 'both',labeller = label_both)
Error in combine_vars(data, params$plot_env, cols, drop = params$drop)
: At least one layer must contain all variables used for facetting
You can use a string inside facet_grid, but you have to provide the whole formula (including the tilde) as a string.
names <- paste(c(". ~ ", names(mtcars)[c(1,3,5)]), collapse='+')
ggplot(mtcars, aes("", hp)) +
geom_boxplot(width=0.7, position=position_dodge(0.7)) +
theme_bw() +
facet_grid(names, switch = 'both', labeller = label_both)
Specifically, this is in a facet_grid. Have googled extensively for similar questions but not clear on the syntax or where it goes. What I want is for every number on the y-axes to have two digits after the decimal, even if the trailing one is 0. Is this a parameter in scale_y_continuous or element_text or...?
row1 <- ggplot(sector_data[sector_data$sector %in% pages[[x]],], aes(date,price)) + geom_line() +
geom_hline(yintercept=0,size=0.3,color="gray50") +
facet_grid( ~ sector) +
scale_x_date( breaks='1 year', minor_breaks = '1 month') +
scale_y_continuous( labels = ???) +
theme(panel.grid.major.x = element_line(size=1.5),
axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.title.y=element_blank(),
axis.text.y=element_text(size=8),
axis.ticks=element_blank()
)
From the help for ?scale_y_continuous, the argument 'labels' can be a function:
labels One of:
NULL for no labels
waiver() for the default labels computed by the transformation object
A character vector giving labels (must be same length as breaks)
A function that takes the breaks as input and returns labels as output
We will use the last option, a function that takes breaks as an argument and returns a number with 2 decimal places.
#Our transformation function
scaleFUN <- function(x) sprintf("%.2f", x)
#Plot
library(ggplot2)
p <- ggplot(mpg, aes(displ, cty)) + geom_point()
p <- p + facet_grid(. ~ cyl)
p + scale_y_continuous(labels=scaleFUN)
The "scales" package has some nice functions for formatting the axes. One of these functions is number_format(). So you don't have to define your function first.
library(ggplot2)
# building on Pierre's answer
p <- ggplot(mpg, aes(displ, cty)) + geom_point()
p <- p + facet_grid(. ~ cyl)
# here comes the difference
p + scale_y_continuous(
labels = scales::number_format(accuracy = 0.01))
# the function offers some other nice possibilities, such as controlling your decimal
# mark, here ',' instead of '.'
p + scale_y_continuous(
labels = scales::number_format(accuracy = 0.01,
decimal.mark = ','))
The scales package has been updated, and number_format() has been retired. Use label_number(). This can also be applied to percentages and other continuous scales (ex: label_percent(); https://scales.r-lib.org/reference/label_percent.html).
#updating Rtists answer with latest syntax from scales
library(ggplot2); library(scales)
p <- ggplot(mpg, aes(displ, cty)) + geom_point()
p <- p + facet_grid(. ~ cyl)
# number_format() is retired; use label_number() instead
p + scale_y_continuous(
labels = label_number(accuracy = 0.01)
)
# for whole numbers use accuracy = 1
p + scale_y_continuous(
labels = label_number(accuracy = 1)
)
Several people have suggested the scales package, but you could just do pretty much the same with base R as well, here by using the format() function.
require(ggplot2)
ggplot(iris, aes(y = Sepal.Length, x = Sepal.Width)) +
geom_point() +
scale_y_continuous(labels = function(x) format(x, nsmall = 2)) +
facet_wrap(~Species)