Home > database >  Highlight only the X-axis between two points in ggplot
Highlight only the X-axis between two points in ggplot

Time:03-21

I have some code that plots two curves below and I would like to highlight the x-axis in the region between where the curves intersect the x-axis

library("ggplot2")


eq1 = function(x){1 ((3.5*(x*x))/(x 3.5)^2)-3.5}
eq2 = function(x){-1 (((x*x*x))/(x 3.5)^2)}

shift_axis <- function(p, y=0, x=0){
  g <- ggplotGrob(p)
  dummy <- data.frame(y=y)
  ax <- g[["grobs"]][g$layout$name == "axis-b"][[1]]
  p   annotation_custom(grid::grobTree(ax, vp = grid::viewport(y=1, height=sum(ax$height))), 
                        ymax=y, ymin=y)  
    geom_hline(aes(yintercept=y), data = dummy)  
    theme(axis.text.x = element_blank(), 
          axis.ticks.x=element_blank())

}



p <- ggplot(data.frame(x=c(0, 40)), aes(x=x))   
  stat_function(fun=eq1, colour="blue") ylim(-1, 3)   theme_bw() stat_function(fun=eq2, colour="green")  
  labs(y=expression(V[2]), x=expression(V[1]))
shift_axis(p, 0)

This is the current output:

enter image description here

Ideally, the x-axis between ~3 and ~20 would be highlighted. Thanks!

CodePudding user response:

Based on @MYaseen208's comment, I used annotate:

library("ggplot2")


eq1 = function(x){1 ((3.5*(x*x))/(x 3.5)^2)-3.5}
eq2 = function(x){-1 (((x*x*x))/(x 3.5)^2)}

shift_axis <- function(p, y=0, x=0){
  g <- ggplotGrob(p)
  dummy <- data.frame(y=y)
  ax <- g[["grobs"]][g$layout$name == "axis-b"][[1]]
  p   annotation_custom(grid::grobTree(ax, vp = grid::viewport(y=1, height=sum(ax$height))), 
                        ymax=y, ymin=y)  
    geom_hline(aes(yintercept=y), data = dummy)  
    theme(axis.text.x = element_blank(), 
          axis.ticks.x=element_blank())

}



p <- ggplot(data.frame(x=c(0, 40)), aes(x=x))   
  stat_function(fun=eq1, colour="blue") ylim(-1, 3)   theme_bw() stat_function(fun=eq2, colour="green")  
  labs(y=expression(V[2]), x=expression(V[1]))  annotate("rect", xmin=3.75, xmax=19.1, ymin=-0.05 , ymax=0.05, alpha=0.2, color="red", fill="red")
shift_axis(p, 0)

The result looks like this:

enter image description here

CodePudding user response:

You could also use I facet zoom() from library(ggforce) to zoom in on a section of an axis with explicit limits.

Sample code:

library(ggplot2)
library(ggforce)
library(ggthemes)

eq1 = function(x){1 ((3.5*(x*x))/(x 3.5)^2)-3.5}
eq2 = function(x){-1 (((x*x*x))/(x 3.5)^2)}

shift_axis <- function(p, y=0, x=0)
  {
  g <- ggplotGrob(p)
  dummy <- data.frame(y=y)
  ax <- g[["grobs"]][g$layout$name == "axis-b"][[1]]
  p   annotation_custom(grid::grobTree(ax, vp = grid::viewport(y=1, height=sum(ax$height))), 
                        ymax=y, ymin=y)  
    geom_hline(aes(yintercept=y), data = dummy)  
    theme(axis.text.x = element_blank(), 
          axis.ticks.x=element_blank())
  
}

     p<-ggplot(data.frame(x=c(0, 40)), aes(x=x))   
      stat_function(fun=eq1, colour="blue", lwd=2) 
      stat_function(fun=eq2, colour="green", lwd=2) 
      ylim(-1, 3)   
      labs(x="Equation 1", y="Equation 2") 
      theme_linedraw() 
      theme(axis.text.x = element_text(hjust = 1, face="bold", size=12, color="black"), 
            axis.title.x = element_text( face="bold", size=16, color="black"),
            axis.text.y = element_text( face="bold", size=12, color="black"),
            axis.title.y = element_text(face="bold", size=16, color="black"),
            strip.text = element_text(size=10, face="bold"),
            plot.title = element_text(size=20, face="bold"),
            legend.position = "none") 
       geom_rect(aes(xmin=3.75, xmax=18.8, ymin=-0.02 , ymax=0.02),
                color="red",
                alpha=0.5,
                inherit.aes = FALSE)
      
     
       
     
     shift_axis(p, 0)
     
     p facet_zoom(xlim = c(3.75, 18.8))  
       scale_x_continuous(breaks=c(3.75, 10, 15, 18.8))            
   

Plot: enter image description here

  • Related