Remove grid, background color, and top and right borders from ggplot2

RGgplot2

R Problem Overview


I would like to reproduce the plot immediately below by using ggplot2. I can come close, but cannot remove the top and right borders. Below I present several attempts using ggplot2, including several suggestions found on or via Stackoverflow. Unfortunately I have not been able to get those suggestions to work.

I am hoping someone may be able to correct one or more of the code snippets below.

Thank you for any suggestions.

# desired plot
a <- seq(1,20)
b <- a^0.25
plot(a,b, bty = "l")


library(ggplot2)

df <- as.data.frame(cbind(a,b))

# 1. ggplot2 default
ggplot(df, aes(x = a, y = b)) + geom_point()

# 2. removes background color
ggplot(df, aes(x = a, y = b)) + geom_point() + opts(panel.background = theme_rect(fill='white', colour='black'))

# 3. also removes gridlines
none <- theme_blank()
ggplot(df, aes(x = a, y = b)) + geom_point() + opts(panel.background = theme_rect(fill='white', colour='black')) + opts(panel.grid.major = none, panel.grid.minor = none)

# 4. does not remove top and right border
ggplot(df, aes(x = a, y = b)) + geom_point() + opts(panel.background = theme_rect(fill='white', colour='black')) + opts(panel.grid.major = none, panel.grid.minor = none) + opts(panel.border = none)

# 5. does not remove top and right border
ggplot(df, aes(x = a, y = b)) + geom_point() + opts(panel.background = theme_rect(fill='white', colour='black')) + opts(panel.grid.major = none, panel.grid.minor = none) + opts(axis.line = theme_segment())

# 6. removes x and y axis in addition to top and right border
# http://stackoverflow.com/questions/5458409/remove-top-and-right-border-from-ggplot2
ggplot(df, aes(x = a, y = b)) + geom_point() + opts(panel.background = theme_rect(fill='white', colour='black')) + opts(panel.grid.major = none, panel.grid.minor = none) + opts(panel.background=theme_rect(colour=NA))

# 7. returns error when attempting to remove top and right border
# https://groups.google.com/group/ggplot2/browse_thread/thread/f998d113638bf251
#
# Error in el(...) : could not find function "polylineGrob"
#
theme_L_border <- function(colour = "black", size = 1, linetype = 1) { 
   structure( 
     function(x = 0, y = 0, width = 1, height = 1, ...) { 
       polylineGrob( 
         x=c(x+width, x, x), y=c(y,y,y+height), ..., default.units = "npc", 
         gp=gpar(lwd=size, col=colour, lty=linetype), 
       ) 
     }, 
     class = "theme", 
     type = "box", 
     call = match.call() 
   )
}

ggplot(df, aes(x = a, y = b)) + geom_point() + opts(panel.background = theme_rect(fill='white', colour='black')) + opts(panel.grid.major = none, panel.grid.minor = none) + opts( panel.border = theme_L_border())

R Solutions


Solution 1 - R

EDIT Ignore this answer. There are now better answers. See the comments. Use + theme_classic()

EDIT

This is a better version. The bug mentioned below in the original post remains (I think). But the axis line is drawn under the panel. Therefore, remove both the panel.border and panel.background to see the axis lines.

library(ggplot2)
a <- seq(1,20)
b <- a^0.25
df <- data.frame(a,b)

ggplot(df, aes(x = a, y = b)) + geom_point() +
  theme_bw() +
  theme(axis.line = element_line(colour = "black"),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_blank(),
    panel.background = element_blank()) 

enter image description here

Original post This gets close. There was a bug with axis.line not working on the y-axis (see here), that appears not to be fixed yet. Therefore, after removing the panel border, the y-axis has to be drawn in separately using geom_vline.

library(ggplot2)
library(grid)

a <- seq(1,20)
b <- a^0.25
df <- data.frame(a,b)

p = ggplot(df, aes(x = a, y = b)) + geom_point() +
   scale_y_continuous(expand = c(0,0)) +
   scale_x_continuous(expand = c(0,0)) +
   theme_bw() +
   opts(axis.line = theme_segment(colour = "black"),
		panel.grid.major = theme_blank(),
		panel.grid.minor = theme_blank(),
		panel.border = theme_blank()) +
	geom_vline(xintercept = 0)
p

The extreme points are clipped, but the clipping can be undone using code by baptiste.

gt <- ggplot_gtable(ggplot_build(p))
gt$layout$clip[gt$layout$name=="panel"] <- "off"
grid.draw(gt)

enter image description here

Or use limits to move the boundaries of the panel.

ggplot(df, aes(x = a, y = b)) + geom_point() +
   xlim(0,22) +  ylim(.95, 2.1) +
   scale_x_continuous(expand = c(0,0), limits = c(0,22)) +
   scale_y_continuous(expand = c(0,0), limits = c(.95, 2.2)) +   
   theme_bw() +
   opts(axis.line = theme_segment(colour = "black"),
		panel.grid.major = theme_blank(),
		panel.grid.minor = theme_blank(),
		panel.border = theme_blank()) +
	geom_vline(xintercept = 0)

Solution 2 - R

Recent updates to ggplot (0.9.2+) have overhauled the syntax for themes. Most notably, opts() is now deprecated, having been replaced by theme(). Sandy's answer will still (as of Jan '12) generates a chart, but causes R to throw a bunch of warnings.

Here's updated code reflecting current ggplot syntax:

library(ggplot2)
a <- seq(1,20)
b <- a^0.25
df <- as.data.frame(cbind(a,b))

#base ggplot object
p <- ggplot(df, aes(x = a, y = b))

p +
  #plots the points
  geom_point() +
  
  #theme with white background
  theme_bw() +
  
  #eliminates background, gridlines, and chart border
  theme(
    plot.background = element_blank(),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_blank()
  ) +
  
  #draws x and y axis line
  theme(axis.line = element_line(color = 'black'))

generates:

plot output

Solution 3 - R

An alternative to theme_classic() is the theme that comes with the cowplot package, theme_cowplot() (loaded automatically with the package). It looks similar to theme_classic(), with a few subtle differences. Most importantly, the default label sizes are larger, so the resulting figures can be used in publications without further modifications needed (in particular if you save them with save_plot() instead of ggsave()). Also, the background is transparent, not white, which may be useful if you want to edit the figure in illustrator. Finally, faceted plots look better, in my opinion.

Example:

library(cowplot)
a <- seq(1,20)
b <- a^0.25
df <- as.data.frame(cbind(a,b))
 
p <- ggplot(df, aes(x = a, y = b)) + geom_point()
save_plot('plot.png', p) # alternative to ggsave, with default settings that work well with the theme

This is what the file plot.png produced by this code looks like: enter image description here

Disclaimer: I'm the package author.

Solution 4 - R

I followed Andrew's answer, but I also had to follow https://stackoverflow.com/a/35833548 and set the x and y axes separately due to a bug in my version of ggplot (v2.1.0).

Instead of

theme(axis.line = element_line(color = 'black'))

I used

theme(axis.line.x = element_line(color="black", size = 2),
    axis.line.y = element_line(color="black", size = 2))

Solution 5 - R

The above options do not work for maps created with sf and geom_sf(). Hence, I want to add the relevant ndiscr parameter here. This will create a nice clean map showing only the features.

library(sf)
library(ggplot2)

ggplot() + 
  geom_sf(data = some_shp) + 
  theme_minimal() +                     # white background
  theme(axis.text = element_blank(),    # remove geographic coordinates
        axis.ticks = element_blank()) + # remove ticks
  coord_sf(ndiscr = 0)                  # remove grid in the background

Solution 6 - R

Simplification from the above Andrew's answer leads to this key theme to generate the half border.

theme (panel.border = element_blank(),
       axis.line    = element_line(color='black'))

Solution 7 - R

Here's an extremely simple answer

yourPlot +
  theme(
    panel.border = element_blank(), 
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(), 
    axis.line = element_line(colour = "black")
    )

It's that easy. Source: the end of this article

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMark MillerView Question on Stackoverflow
Solution 1 - RSandy MusprattView Answer on Stackoverflow
Solution 2 - RAndrewView Answer on Stackoverflow
Solution 3 - RClaus WilkeView Answer on Stackoverflow
Solution 4 - Rwinni2kView Answer on Stackoverflow
Solution 5 - RlokiView Answer on Stackoverflow
Solution 6 - RSJ9View Answer on Stackoverflow
Solution 7 - RstevecView Answer on Stackoverflow