最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

r - Is there a way to add an axis break in ggplot using scale_y_break - Stack Overflow

programmeradmin1浏览0评论

I am looking to add an axis break in ggplot at 1.0 to 2.5 on the Y scale with the top break smaller than the bottom break such as in the photo below. But when using the scale_y_break(c(1.0, 2.5)) it causes the two panels before/after the break to be the same scale causing the top panel to be too large. Is there anyway to fix this issue?

What I want.

what Im getting.

# Generate fake ammonia load data
set.seed(123)  # For reproducibility
dates <- seq(as.Date("2024-01-01"), as.Date("2024-12-31"), by="week")
ammonia_load <- runif(length(dates), min=0, max=0.35)  # Random data between 0 and 0.35

# Create a data frame
df <- data.frame(Date = dates, `Amonia Load` = ammonia_load)
df


### Change with separation !!!!!!!!!!!
# Create Top plot 
Figure = ggplot(df, aes(x=Date, y=`Amonia.Load`)) +
  geom_point(color="black", fill="blue", shape=21, size=2) +
  labs(x="", y="Load (kg/day)") +
  theme_classic() +
  scale_x_date(date_breaks="1 month", date_labels="%b") +
  scale_y_continuous(limits=c(0.0, 3.0), breaks = c(0.0,0.2,0.4,0.6,0.8,1.0,2.5,3.0)) +
  theme(panel.border = element_rect(color="black", fill=NA, size=0.5), text = element_text(size=12), axis.text = element_text(size=12), 
        axis.title = element_text(size=12)) +
  geom_hline(yintercept=2.8, linetype="dashed", color="black") +
  scale_y_break(c(1.0, 2.5)) 
Figure

I am looking to add an axis break in ggplot at 1.0 to 2.5 on the Y scale with the top break smaller than the bottom break such as in the photo below. But when using the scale_y_break(c(1.0, 2.5)) it causes the two panels before/after the break to be the same scale causing the top panel to be too large. Is there anyway to fix this issue?

What I want.

what Im getting.

# Generate fake ammonia load data
set.seed(123)  # For reproducibility
dates <- seq(as.Date("2024-01-01"), as.Date("2024-12-31"), by="week")
ammonia_load <- runif(length(dates), min=0, max=0.35)  # Random data between 0 and 0.35

# Create a data frame
df <- data.frame(Date = dates, `Amonia Load` = ammonia_load)
df


### Change with separation !!!!!!!!!!!
# Create Top plot 
Figure = ggplot(df, aes(x=Date, y=`Amonia.Load`)) +
  geom_point(color="black", fill="blue", shape=21, size=2) +
  labs(x="", y="Load (kg/day)") +
  theme_classic() +
  scale_x_date(date_breaks="1 month", date_labels="%b") +
  scale_y_continuous(limits=c(0.0, 3.0), breaks = c(0.0,0.2,0.4,0.6,0.8,1.0,2.5,3.0)) +
  theme(panel.border = element_rect(color="black", fill=NA, size=0.5), text = element_text(size=12), axis.text = element_text(size=12), 
        axis.title = element_text(size=12)) +
  geom_hline(yintercept=2.8, linetype="dashed", color="black") +
  scale_y_break(c(1.0, 2.5)) 
Figure

Share Improve this question asked Mar 14 at 20:51 confusedindividualconfusedindividual 6414 silver badges17 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

The easiest way to do this is by adjusting your upper plot limit to, say, 2.7, and faking the upper y axis label to read "3".

You'll need to ensure your geom_hline is in the correct position to represent 2.8 in this scale (i.e. at y = 2.62, since 2.62 is three-fifths of the way between 2.5 and 2.7 just as 2.8 is three-fifths of the way between 2.5 and 3).

library(ggplot2)
library(ggbreak)

ggplot(df, aes(x = Date, y = `Amonia.Load`)) +
  geom_point(color = "black", fill = "blue", shape = 21, size = 2) +
  geom_hline(yintercept = 2.62, linetype = "dashed", color ="black") +
  scale_x_date(name = NULL, date_breaks = "1 month", date_labels = "%b") +
  scale_y_continuous(name   =  "Load (kg/day)",
                     limits = c(0.0, 2.7), 
                     breaks = c(seq(0, 1, 0.2), 2.5, 2.7),
                     labels = c(seq(0, 1, 0.2), 2.5, 3)) +
  scale_y_break(breaks = c(1.0, 2.5)) +
  theme_classic() +
  theme(panel.border = element_rect(color = "black", fill = NA, size = 0.5), 
        text         = element_text(size = 12), 
        axis.text    = element_text(size = 12), 
        axis.title   = element_text(size = 12))

This may seem a bit hacky, but it is far simpler than writing a new transformation object to apply to the axis. For completeness, here is how you would do it "properly"

library(scales)

transform_squeeze <- function(from, ratio) {
  
  new_transform("squeeze", 
                transform = \(x) ifelse(x > from, (x - from)/ratio + from, x),
                inverse = \(x) ifelse(x > from, (x - from) * ratio + from, x))
}


ggplot(df, aes(x = Date, y = `Amonia.Load`)) +
  geom_point(color = "black", fill = "blue", shape = 21, size = 2) +
  geom_hline(yintercept = 2.8, linetype = "dashed", color ="black") +
  scale_x_date(name = NULL, date_breaks = "1 month", date_labels = "%b") +
  scale_y_continuous(name   =  "Load (kg/day)",
                     transform = transform_squeeze(2.5, ratio = 2.5),
                     limits = c(0.0, 3), 
                     breaks = c(seq(0, 1, 0.2), 2.5, 3)) +
  scale_y_break(breaks = c(1.0, 2.5)) +
  theme_classic() +
  theme(panel.border = element_rect(color = "black", fill = NA, size = 0.5), 
        text         = element_text(size = 12), 
        axis.text    = element_text(size = 12), 
        axis.title   = element_text(size = 12))

Note that this gives identical visual results despite the increased complexity. However, it easily allows you to specify the threshold above which you start to compress the axis and the compression ratio to control the size of the upper panel, all without having to change your breaks, hline level and axis labels.

发布评论

评论列表(0)

  1. 暂无评论