rggplot2axis

How to remove extra segment on y-axis in combined ggplot2 plots?


enter image description hereI'm using ggplot2 in R to create a set of plots, which I then arrange into a single composite figure using grid.arrange from the gridExtra package. Although I managed to position the plots closely together, the barplots in the top-left and bottom-right positions show an unwanted extra segment at the bottom of their y-axes. I need help removing these segments.

Here's a simplified version of the data and the code I'm using:

set.seed(444)  


var1 <- rnorm(100, mean = 50, sd = 10)  
var2 <- runif(100, min = 0, max = 100)
categories <- c("Category A", "Category B", "Category C")
var3 <- sample(categories, 100, replace = TRUE)

jesper_data_random <- data.frame(
  Forces = var1,
  Separation = var2,
  Coloring = var3
)

And here is the code I am using for the plot:


main_plot <- jesper_data_random %>%
  ggplot(aes(
    x = Separation,
    y = Forces,
    colour=Coloring
  )) +
  geom_point() +
  labs(x="Distance", y="Force")+
  scale_x_continuous(position="top",
                     expand = expansion(mult = c(0.005, 0.005))
                     ) +
  scale_y_continuous(position="right",
                     expand = expansion(mult = c(0.005, 0.005))
                     ) +
  theme(
    plot.margin = margin(0,0,-70,-70)
    ) +
  theme_bw() +
  coord_cartesian(clip = "off")


xplot <- ggplot(jesper_data_random, aes(x = Separation)) +
  geom_histogram(aes(fill = Coloring, color = Coloring), bins = 30) +
  scale_y_continuous(
    expand = expansion(mult = c(0.005, 0.005))
    ) +
  scale_x_continuous(
    expand = expansion(mult = c(0.005, 0.005))
    ) +
  theme_classic() +
  theme(
    axis.ticks.x = element_blank(),
    axis.title.x = element_blank(),
    axis.text.x = element_blank(),
    plot.margin = margin(0,40,0,-29)
  )

xplot <- xplot + scale_y_reverse()


yplot <- ggplot(jesper_data_random, aes(x = Forces)) +
  geom_histogram(aes(fill = Coloring, color = Coloring), bins = 30) +
   scale_y_continuous(
     expand = expansion(mult = c(0.005, 0.005))
   ) +
  
   scale_x_continuous(
     expand = expansion(mult = c(0.005, 0.005))
   ) +
  theme_classic() +
  theme(
    axis.ticks.y = element_blank(),
    axis.title.y = element_blank(),
    axis.text.y = element_blank(),
    plot.margin = margin(35,0,-23,0)
  ) +
  rotate()

yplot <- yplot + scale_y_reverse()


# Cleaning the plots
main_plot <- main_plot + rremove("legend")
yplot <- yplot +  rremove("legend") 
xplot <- xplot + rremove("legend")


blank_plot <- ggplot() + 
  theme_void() + 
  theme(plot.background = element_blank(),
        panel.grid = element_blank(),
        #plot.margin = unit(c(0,0,0,0), "lines"),
        plot.margin = margin(0,0,0,0))

grid.arrange(grobs = list(yplot, main_plot, blank_plot, xplot), ncol = 2)

The barplots xplot and yplot have an extra segment at the bottom of their y-axes, which I want to remove. How can I adjust the y-axis to eliminate this segment, or is there another way to clean up the axis appearance in these plots?

In the picture I have indicated the segments I would like to remove

Initially, I suspected that the problem might be related to the plot margins. After extensively adjusting the margin settings, I confirmed that the margins are set correctly, and they allow the plots to be positioned closely in the combined structure. However, the issue with the extra segment on the y-axis persisted. Upon further investigation, I noticed that this segment only appears after applying scale_y_reverse(). I've searched extensively but haven't found a solution to remove this unwanted segment. Any insights or suggestions would be greatly appreciated.


Solution

  • If you use the ggplot2 >= 3.5.0, you can "cap" your axis line using guide_axis() (https://www.tidyverse.org/blog/2024/02/ggplot2-3-5-0-axes/#capping).

    Using your example, it can be done by adding this guide_axis() to xplot and yplot:

    xplot <- ggplot(jesper_data_random, aes(x = Separation)) +
      geom_histogram(aes(fill = Coloring, color = Coloring), bins = 30) +
      scale_y_continuous(
        expand = expansion(mult = c(0.005, 0.005))
      ) +
      scale_x_continuous(
        expand = expansion(mult = c(0.005, 0.005))
      ) +
      theme_classic() +
      theme(
        axis.ticks.x = element_blank(),
        axis.title.x = element_blank(),
        axis.text.x = element_blank(),
        plot.margin = margin(0,40,0,-29)
      ) +
      guides(y = guide_axis(cap = "both"))
    
    yplot <- ggplot(jesper_data_random, aes(x = Forces)) +
      geom_histogram(aes(fill = Coloring, color = Coloring), bins = 30) +
      scale_y_continuous(
        expand = expansion(mult = c(0.005, 0.005))
      ) +
      
      scale_x_continuous(
        expand = expansion(mult = c(0.005, 0.005))
      ) +
      theme_classic() +
      theme(
        axis.ticks.y = element_blank(),
        axis.title.y = element_blank(),
        axis.text.y = element_blank(),
        plot.margin = margin(35,0,-23,0)
      ) +
      guides(x = guide_axis(cap = "both")) +
      rotate()
    

    enter image description here