Set the same Y scale for different plots
3
0
Entering edit mode
6 months ago
G.S ▴ 60

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 • 1.2k views
ADD COMMENT
0
Entering edit mode
ADD REPLY
3
Entering edit mode
6 months ago
LauferVA 4.5k

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

ADD COMMENT
1
Entering edit mode

I think we need min/max from both datasets.

ADD REPLY
1
Entering edit mode

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 ...

ADD REPLY
0
Entering edit mode

good point.

OK, I have emended my answer above. Thoughts?

ADD REPLY
1
Entering edit mode

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?

ADD REPLY
0
Entering edit mode

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.

ADD REPLY
3
Entering edit mode
6 months ago
ATpoint 85k

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.

ADD COMMENT
2
Entering edit mode
6 months ago
Medhat 9.8k

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)) +  
...
ADD COMMENT
0
Entering edit mode

Or use range:

my_y_limits <- range(c(mtcars$cyl, mtcars$mpg))
my_y_limits
# [1]  4.0 33.9
ADD REPLY
0
Entering edit mode
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()`). 
> 
ADD REPLY

Login before adding your answer.

Traffic: 1992 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6