Remover grade, cor de fundo e bordas superior e direita do ggplot2

103

Eu gostaria de reproduzir o gráfico imediatamente abaixo usando ggplot2. Posso chegar perto, mas não consigo remover as bordas superior e direita. A seguir, apresento várias tentativas de usar ggplot2, incluindo várias sugestões encontradas no ou por meio do Stackoverflow. Infelizmente, não consegui fazer com que essas sugestões funcionassem.

Espero que alguém consiga corrigir um ou mais dos trechos de código abaixo.

Obrigado por qualquer sugestão.

# 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())
Mark Miller
fonte
3
conforme postado em um comentário abaixo, isso agora pode ser feito com + theme_classic ()
nsheff

Respostas:

133

EDIT Ignore esta resposta. Agora existem respostas melhores. Veja os comentários. Usar+ theme_classic()

EDITAR

Esta é uma versão melhor. O bug mencionado abaixo na postagem original permanece (eu acho). Mas a linha do eixo é desenhada sob o painel. Portanto, remova panel.bordere panel.backgroundpara ver as linhas do eixo.

library(ggplot2)
a <- seq(1,20)
b <- a^0.25
df <- as.data.frame(cbind(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()) 

insira a descrição da imagem aqui

Postagem original Isso chega perto. Havia um bug com o axis.linenão funcionamento do eixo y ( veja aqui ), que parece não ter sido corrigido ainda. Portanto, após remover a borda do painel, o eixo y deve ser desenhado separadamente usando geom_vline.

library(ggplot2)
library(grid)

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() +
   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

Os pontos extremos são recortados, mas o recorte pode ser desfeito usando o código de baptiste .

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

insira a descrição da imagem aqui

Ou use limitspara mover os limites do painel.

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)
Sandy Muspratt
fonte
76

As atualizações recentes do ggplot (0.9.2+) revisaram a sintaxe dos temas. Mais notavelmente, opts()agora está obsoleto, tendo sido substituído por theme(). A resposta de Sandy ainda (a partir de janeiro de 12) gerará um gráfico, mas fará com que R lance um monte de avisos.

Este é o código atualizado que reflete a sintaxe atual do ggplot:

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'))

gera:

saída do gráfico

Andrew
fonte
33
ou mais simplesmente? ggplot (df, aes (x = a, y = b)) + geom_point () + theme_classic ()
user20650
Nenhuma dessas abordagens funciona para mim usando ggplot2 2.1.0 ... a resposta de @wkretzsch foi boa.
Nova
25

Uma alternativa ao theme_classic()é o tema que vem com o pacote cowplot , theme_cowplot()(carregado automaticamente com o pacote). É semelhante a theme_classic(), com algumas diferenças sutis. Mais importante ainda, os tamanhos de etiqueta padrão são maiores, de modo que os números resultantes podem ser usados ​​em publicações sem a necessidade de modificações adicionais (em particular se você salvá-los com em save_plot()vez de ggsave()). Além disso, o fundo é transparente, não branco, o que pode ser útil se você quiser editar a figura no ilustrador. Finalmente, os gráficos facetados parecem melhores, em minha opinião.

Exemplo:

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

Esta é a plot.pngaparência do arquivo produzido por este código: insira a descrição da imagem aqui

Isenção de responsabilidade: eu sou o autor do pacote.

Claus Wilke
fonte
8

Segui a resposta de Andrew , mas também tive que seguir https://stackoverflow.com/a/35833548 e definir os eixos xey separadamente devido a um bug em minha versão do ggplot (v2.1.0).

Ao invés de

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

eu usei

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

As opções acima não funcionam para mapas criados com sfe geom_sf(). Portanto, quero adicionar o ndiscrparâmetro relevante aqui. Isso criará um bom mapa limpo mostrando apenas os recursos.

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
loki
fonte
1

A simplificação da resposta de Andrew acima leva a esse tema-chave para gerar a meia borda.

theme (panel.border = element_blank(),
       axis.line    = element_line(color='black'))
Sibo Jiang
fonte
0

Aqui está uma resposta extremamente simples

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

É tão fácil. Fonte: final deste artigo

Stevec
fonte