This is a test version of Biostars. For the public version, visit https://www.biostars.org.
Set the same Y scale for different plots

Dear,

I would like to make the scale similar in all plots. Any idea how to do it?

Here is my code

a_filtered <- a %>%
  filter(name == "norm_CntTs", !is.na(coding))


plot <- ggplot(a_filtered, aes(x = Condition, y = value, color = Condition)) +
  geom_boxplot(width = 0.5, show.legend = FALSE) +
  scale_y_log10() +
  scale_size(range = c(0, 0.2))+
  scale_color_manual(values = c("HRSV" = "#eb4a40", "HRSV_RBV" = "#045275")) +
  facet_wrap(. ~ coding, ncol = 2) +
  labs(title = "Ts", y = "Average Ts count") +
  theme_bw() +
  theme(text = element_text(size = 19, face="bold"),
        plot.title = element_text(hjust = 0.5),
        strip.text = element_text(face = "bold"))

p1 <- plot + stat_compare_means(method = "wilcox.test",comparisons = my_comparisons,size= 4.5, hjust= 0.09,vjust=-0.2, alternative = "two.sided",
                          paired = F, label = "p.value")

p1

a_filtered_tv <- a %>%
  filter(name == "norm_CntTv", !is.na(coding))


plot <- ggplot(a_filtered_tv , aes(x = Condition, y = value, color = Condition)) +
  geom_boxplot(width = 0.5, show.legend = FALSE) +
  scale_y_log10() +
  scale_size(range = c(0.01, 0.2))+
  scale_color_manual(values = c("HRSV" = "#eb4a40", "HRSV_RBV" = "#045275")) +
  facet_wrap(. ~ coding, ncol = 2) +
  labs(title = "Tv", y = "Average Tv count") +
  theme_bw() +
  theme(text = element_text(size = 19, face="bold"),
        plot.title = element_text(hjust = 0.5),
        strip.text = element_text(face = "bold"))

p2 <-plot + stat_compare_means(method = "wilcox.test",comparisons = my_comparisons,size= 4.5, hjust= 0.09,vjust=-0.2, alternative = "two.sided",
                          paired = F, label = "p.value")

p1+p2 +
  facet_wrap(. ~ coding, ncol = 2)

Thanks in advance enter image description here

ggplot2 r

3 answers

Hello Ghada ,

Ok, I revised my answer based on the error message you posted, below. I marked the areas where the main changes are like this: ########.

It's most likely the error is being generated when you call scale_y_log10() which could produce Inf or -Inf values. You can prevent that by restricting the input values to positive values only:

library(ggplot2)
library(dplyr)
library(ggpubr)
library(patchwork)

######## Begin by getting y_limits for both plots:
# Filter and prepare data for the first plot
a_filtered <- a %>%
  filter(name == "norm_CntTs", !is.na(coding), value > 0)  # Ensure only positive values for log scale

# Filter and prepare data for the second plot
a_filtered_tv <- a %>%
  filter(name == "norm_CntTv", !is.na(coding), value > 0)  # Ensure only positive values for log scale

# Combine the y-axis limits from both datasets
combined_data <- bind_rows(a_filtered, a_filtered_tv)
y_limits <- c(min(combined_data$value, na.rm = TRUE), max(combined_data$value, na.rm = TRUE))  # Define y-axis limits based on both datasets
########  now, can use y_limits in both plots below:

# Create the first plot with specified y-axis limits
plot1 <- ggplot(a_filtered, aes(x = Condition, y = value, color = Condition)) +
  geom_boxplot(width = 0.5, show.legend = FALSE) +
  scale_y_log10() +
  coord_cartesian(ylim = y_limits) +  # Apply consistent y-axis limits
  scale_size(range = c(0, 0.2))+
  scale_color_manual(values = c("HRSV" = "#eb4a40", "HRSV_RBV" = "#045275")) +
  facet_wrap(. ~ coding, ncol = 2) +
  labs(title = "Ts", y = "Average Ts count") +
  theme_bw() +
  theme(text = element_text(size = 19, face="bold"),
        plot.title = element_text(hjust = 0.5),
        strip.text = element_text(face = "bold"))

p1 <- plot1 + stat_compare_means(method = "wilcox.test", comparisons = my_comparisons, size= 4.5, hjust= 0.09, vjust=-0.2, alternative = "two.sided", paired = FALSE, label = "p.value")

# Create the second plot with the same y-axis limits
plot2 <- ggplot(a_filtered_tv , aes(x = Condition, y = value, color = Condition)) +
  geom_boxplot(width = 0.5, show.legend = FALSE) +
  scale_y_log10() +
  coord_cartesian(ylim = y_limits) +  # Apply consistent y-axis limits
  scale_size(range = c(0.01, 0.2))+
  scale_color_manual(values = c("HRSV" = "#eb4a40", "HRSV_RBV" = "#045275")) +
  facet_wrap(. ~ coding, ncol = 2) +
  labs(title = "Tv", y = "Average Tv count") +
  theme_bw() +
  theme(text = element_text(size = 19, face="bold"),
        plot.title = element_text(hjust = 0.5),
        strip.text = element_text(face = "bold"))

p2 <- plot2 + stat_compare_means(method = "wilcox.test", comparisons = my_comparisons, size= 4.5, hjust= 0.09, vjust=-0.2, alternative = "two.sided", paired = FALSE, label = "p.value")

# Combine the plots
combined_plot <- p1 + p2  # Combine the two plots using patchwork

# Display the combined plot
print(combined_plot)

Does this fix your error message? Let me know and we can keep trying.

VAL

I think we need min/max from both datasets.

good point.

OK, I have emended my answer above. Thoughts?

I added this - also, I think the error message is probably being introduced due to the scale_y_log10() call and the range of the input values being fed into it ...

OK! I emended my answer above. Does it fix the error message?

Error in seq.default(min, max, by = by) : 'from' must be a finite number
In addition: Warning messages:
1: In scale_y_log10() :
  log-10 transformation introduced infinite values.
2: In scale_y_log10() :
  log-10 transformation introduced infinite values.
3: Removed 73722 rows containing non-finite outside the scale range (`stat_boxplot()`). 
4: Removed 73722 rows containing non-finite outside the scale range (`stat_signif()`). 
> 

If it does not, could you provide sample objects so that this is a reproducible example?

Thanks very much for your help! This code works and solves the problem. I really appreciate you going the extra mile and adding a code explanation.

Use +ylim(c(lower, upper)). Either set manually, or query both a_filtered and a_filtered_tv for the minimum and maximum values that go into these plots, and then apply these. Note that this is basic ggplot2 and is more suited for the likes of StackOverflow.

Maybe try to calculate min and max

combined_min <- min(a_filtered$value, a_filtered_tv$value, na.rm = TRUE)
combined_max <- max(a_filtered$value, a_filtered_tv$value, na.rm = TRUE). 

And use these values to limit the y-axis scale for both plots

....  
geom_boxplot(width = 0.5, show.legend = FALSE) +  
scale_y_log10(limits = c(combined_min, combined_max)) +  
...

Or use range:

my_y_limits <- range(c(mtcars$cyl, mtcars$mpg))
my_y_limits
# [1]  4.0 33.9
Error in seq.default(min, max, by = by) : 'from' must be a finite number
In addition: Warning messages:
1: In scale_y_log10(limits = c(combined_min_tv, combined_max_tv)) :
  log-10 transformation introduced infinite values.
2: In scale_y_log10(limits = c(combined_min_tv, combined_max_tv)) :
  log-10 transformation introduced infinite values.
3: Removed 72634 rows containing non-finite outside the scale range (`stat_boxplot()`). 
4: Removed 72634 rows containing non-finite outside the scale range (`stat_signif()`). 
> 

Log in to answer this question.