How to Set Limits For Axes in Ggplot2 R Plots

How to set limits for axes in ggplot2 R plots?

Basically you have two options

scale_x_continuous(limits = c(-5000, 5000))


coord_cartesian(xlim = c(-5000, 5000)) 

Where the first removes all data points outside the given range and the second only adjusts the visible area. In most cases you would not see the difference, but if you fit anything to the data it would probably change the fitted values.

You can also use the shorthand function xlim (or ylim), which like the first option removes data points outside of the given range:

+ xlim(-5000, 5000)

For more information check the description of coord_cartesian.

The RStudio cheatsheet for ggplot2 makes this quite clear visually. Here is a small section of that cheatsheet:

Sample Image

Distributed under CC BY.

Adjusting y axis limits in ggplot2 with facet and free scales

First, reproducibility with random data needs a seed. I started using set.seed(42), but that generated negative values which caused completely unrelated warnings. Being a little lazy, I changed the seed to set.seed(2021), finding all positives.

For #1, we can add limits=, where the help for ?scale_y_continuous says that

  limits: One of:

• 'NULL' to use the default scale range

• A numeric vector of length two providing limits of the
scale. Use 'NA' to refer to the existing minimum or

• A function that accepts the existing (automatic) limits
and returns new limits Note that setting limits on
positional scales will *remove* data outside of the
limits. If the purpose is to zoom, use the limit argument
in the coordinate system (see 'coord_cartesian()').

so we'll use c(0, NA).

For Q2, we'll add expand=, documented in the same place.

data %>%
gather(Gene, Levels, -Patient, -Treatment) %>%
mutate(Treatment = factor(Treatment, levels = c("Pre", "Post"))) %>%
mutate(Patient = as.factor(Patient)) %>%
ggplot(aes(x = Treatment, y = Levels, color = Patient, group = Patient)) +
geom_point() +
geom_line() +
facet_wrap(. ~ Gene, scales = "free") +
theme_bw() +
theme(panel.grid = element_blank()) +
scale_y_continuous(limits = c(0, NA), expand = expansion(mult = c(0, 0.1)))

Sample Image

R ggplot cannot set log axis limits

I think your problem is that log(0) is undefined (or -Inf for R), so you can't set the x limit to 0 on a log transformed axis without getting an error.

My usual workaround is to set the axis limit to 1 (because log(1) = 0), as below.

ggplot(s1_to_5_adj, aes(x = PfMSP119_adj))+
geom_histogram(bins = 1500) +
ylim(c(0,150)) +
scale_x_log10(limit = c(1,25000)) +
xlab("MFI value") +
ylab("Frequency") +
labs(title = "Age 1-5") +
theme(plot.title = element_text(hjust = 0.5)) +

plot with limits at 1 and 25000

Limit the X and Y axes of ggplot2 plot

Add limits and expand arguments in scale_x_continuous and scale_y_continuous. You can add breaks as well.

ggplot( + 
geom_line(aes(x = wt, y = mpg, color= factor(cyl))) +
ylab('Fuel Economy (mpg)') +
scale_y_continuous(limits = c(10, 35), expand = c(0, 0),
sec.axis = sec_axis(~.*1.6/3.7854, name = 'Fuel Economy (kmpl)')
) +
xlab('Weight (lbs)') +
scale_x_continuous(limits = c(0, 5), expand = c(0, 0),
sec.axis = sec_axis(~./2.20462, name = 'Weight (kg)'), position = 'bottom') +
theme_light() +
legend.position = c(0.15, 0.75),
legend.title = element_blank(),
axis.title.y.right = element_text(
angle = 90,
margin = margin(r = 0.8 * 11,
l = 0.8 * 11 / 2)

Sample Image

Conditionally set the xlim or axis limits when making plots in a loop in ggplot2

This could be achieved by setting the limits conditionally via an if-statement. Personally I prefer to use lists and lapply or purrr::map or purrr::walk to make plots in a loop instead of using for but the approach could also be used with a for-loop:

Using mtcars as example dataset:


mtcars_split <- split(mtcars, mtcars$cyl)

plot_function <- function(df, i) {
xlim <- if (max(df$mpg) < 20) {
xlim(0, 20)
} else if (max(df$mpg) < 30) {
xlim(0, 30)
} else {
xlim(0, 40)
ggplot(df, aes(x=mpg ,y=hp))+
geom_point(aes(colour=am)) +
xlim +
ggtitle("Point", i)
ggsave(filename = paste("plot_cyl_", i,".png"), width = 20, height = 20, units = "cm")

Loop over the splitted dataframe using purrr::iwalk

purrr::iwalk(mtcars_split, plot_function)

or using a for loop:

for (i in seq_along(mtcars_split)) {
plot_function(mtcars_split[[i]], names(mtcars_split)[[i]])

How to set just one limit for axes in ggplot2 with facets?

Set limits one-sided with NA. Works both in coord_ and scale_ functions

I generally prefer coord_ because it does not remove data. For the example below you would additionally need to remove the margin at 0, e.g. with expand.


carrots <- data.frame(length = rnorm(500000, 10000, 10000))
cukes <- data.frame(length = rnorm(50000, 10000, 20000))
carrots$veg <- 'carrot'
cukes$veg <- 'cuke'
vegLengths <- rbind(carrots, cukes)

ggplot(vegLengths, aes(length, fill = veg)) +
geom_density(alpha = 0.2) +
scale_x_continuous(limits = c(0, NA))
#> Warning: Removed 94542 rows containing non-finite values (stat_density).

Sample Image

ggplot(vegLengths, aes(length, fill = veg)) +
geom_density(alpha = 0.2) +
coord_cartesian(xlim = c(0, NA))

Sample Image

Created on 2020-04-30 by the reprex package (v0.3.0)

remove the margin with expand. Also one sided possible. the right margin is set to the default mult expansion of 0.05 for continous axis.

ggplot(vegLengths, aes(length, fill = veg)) +
geom_density(alpha = 0.2) +
scale_x_continuous(expand = expansion(mult = c(0, 0.05))) +
coord_cartesian(xlim = c(0, NA))

Sample Image

Manually setting limits and ticks on x-axis after coord_flip() in ggplot2

You want to define a continuous variable's axis, so you should use the scale_y_continuous() function for your plot, and define the breaks you want.

Here's a dummy example :

p <- ggplot(data = iris[c(1:3, 52:55, 102:105),], mapping = aes(x = reorder(Species,-Petal.Width), y = Petal.Width))

p + geom_pointrange(mapping = aes(ymin = 0, ymax = 3)) +
labs(x= "", y= "yvar_label") + coord_flip() +
geom_hline(yintercept = 5, linetype="dotted", color = "red", size=1.5) +
scale_y_continuous(breaks = seq(from = 0, to = 3, by = 0.5), limits = c(0,3)) +

Sample Image

Edit: For plot limits, you should give the limits arguments to the scale_x/y_continuous() function.

Can't set limits for a graph with two y scales

You can't set limits for the secondary axis via the limits argument.

If you want a different scale or limits for the secondary axis you have to scale your data accordingly. My code below makes use of scales::rescale to do the (re-)scaling of your AUC data:


from <- c(0.8, 1)
to <- range(plot_df_AIC$AIC)
plot_df_AUC$AUC <- scales::rescale(plot_df_AUC$AUC, from = from, to = to)

geom_line(data=plot_df_AIC, aes(x=x, y=AIC), color="red") +
geom_line(data=plot_df_AUC, aes(x=x, y=AUC), color="blue")+
scale_y_continuous(sec.axis = sec_axis(
~ scales::rescale(.x, to = from, from = to), name = "AUC"))+
axis.title.y = element_text(color = "red"),
axis.text.y = element_text(color = "red"),
axis.title.y.right = element_text(color = "blue"),
axis.text.y.right = element_text(color = "blue")

Sample Image

Related Topics

Leave a reply