ggplot2: Suspensórios encaracolados em um eixo?

Ao responder a uma pergunta de visualização recente, eu realmente precisava de chaves para mostrar um espaço em um eixo, e não consigo descobrir como fazer isso no ggplot2. Aqui está o enredo:

trama de exemplo

Em vez de uma marca de escala, eu realmente gostaria que o label do eixo y “Segunda letra de nomes de duas letras” tivesse uma chave que se estendesse de 1 a 10 (a extensão vertical das segundas e vermelhas letras azuis). Mas não sei como fazer isso acontecer. O eixo x pode se beneficiar de tratamento similar.

O código está disponível na pergunta CrossValidated vinculada (e desnecessariamente complicada para este exemplo, portanto, não mostrarei isso). Em vez disso, aqui está um exemplo mínimo:

library(ggplot2) x <- c(runif(10),runif(10)+2) y <- c(runif(10),runif(10)+2) qplot(x=x,y=y) + scale_x_continuous("",breaks=c(.5,2.5),labels=c("Low types","High types") ) 

exemplo mínimo

Neste caso, uma chave de (0,1) para tipos baixos e de (2,3) para os tipos altos seria ideal em vez de marcas de escala.

Eu prefiro não usar o geom_rect porque:

  • As marcas de carrapato permanecerão
  • Eu preferiria aparelho
  • Será dentro da trama em vez de fora dela

Como eu conseguiria isso? A resposta perfeita teria:

  • Um belo, suave e fina cinta
  • Desenhar fora da área de plotagem
  • Especificado por meio de um argumento de alto nível (idealmente, um object do tipo de intervalo passado para a opção de breaks em scale_x_continuous )

Atualização: Assegure-se de ver as perguntas e respostas sobre Stackoverflow relacionadas, se precisar salvar o gráfico com ggsave () e deixar os colchetes persistirem na imagem salva.


O OP solicitou que o suporte estivesse fora do enredo. Essa solução usa axis.ticks.length em combinação com axis.ticks = element_blank() para permitir que a chave esteja fora da área de plotagem. Esta resposta se baseia nos do @Pankil e @ user697473: pBrackets pacote pBrackets R – e includeemos imagens!

 library(ggplot2) library(grid) library(pBrackets) x <- c(runif(10),runif(10)+2) y <- c(runif(10),runif(10)+2) the_plot <- qplot(x=x,y=y) + scale_x_continuous("",breaks=c(.5,2.5),labels=c("Low types","High types") ) + theme(axis.ticks = element_blank(), axis.ticks.length = unit(.85, "cm")) #Run grid.locator a few times to get coordinates for the outer #most points of the bracket, making sure the #bottom_y coordinate is just at the bottom of the gray area. # to exit grid.locator hit esc; after setting coordinates # in grid.bracket comment out grid.locator() line the_plot grid.locator(unit="native") bottom_y <- 284 grid.brackets(220, bottom_y, 80, bottom_y, lwd=2, col="red") grid.brackets(600, bottom_y, 440, bottom_y, lwd=2, col="red") 

insira a descrição da imagem aqui

Uma nota rápida na resposta do @Pankil:

 ## Bracket coordinates depend on the size of the plot ## for instance, ## Pankil's suggested bracket coordinates do not work ## with the following sizing: the_plot grid.brackets(240, 440, 50, 440, lwd=2, col="red") grid.brackets(570, 440, 381, 440, lwd=2, col="red") ## 440 seems to be off the graph... 

insira a descrição da imagem aqui

E mais alguns para mostrar a funcionalidade dos pBrackets :

 #note, if you reverse the x1 and x2, the bracket flips: the_plot grid.brackets( 80, bottom_y, 220, bottom_y, lwd=2, col="red") grid.brackets(440, bottom_y, 600, bottom_y, lwd=2, col="red") 

insira a descrição da imagem aqui

 ## go vertical: the_plot grid.brackets(235, 200, 235, 300, lwd=2, col="red") grid.brackets(445, 125, 445, 25, lwd=2, col="red") 

insira a descrição da imagem aqui

Outra solução usando uma function que desenha uma chave.

Obrigado Gur!

 curly <- function(N = 100, Tilt = 1, Long = 2, scale = 0.1, xcent = 0.5, ycent = 0.5, theta = 0, col = 1, lwd = 1, grid = FALSE){ # N determines how many points in each curve # Tilt is the ratio between the axis in the ellipse # defining the curliness of each curve # Long is the length of the straight line in the curly brackets # in units of the projection of the curly brackets in this dimension # 2*scale is the absolute size of the projection of the curly brackets # in the y dimension (when theta=0) # xcent is the location center of the x axis of the curly brackets # ycent is the location center of the y axis of the curly brackets # theta is the angle (in radians) of the curly brackets orientation # col and lwd are passed to points/grid.lines ymin <- scale / Tilt y2 <- ymin * Long i <- seq(0, pi/2, length.out = N) x <- c(ymin * Tilt * (sin(i)-1), seq(0,0, length.out = 2), ymin * (Tilt * (1 - sin(rev(i)))), ymin * (Tilt * (1 - sin(i))), seq(0,0, length.out = 2), ymin * Tilt * (sin(rev(i)) - 1)) y <- c(-cos(i) * ymin, c(0,y2), y2 + (cos(rev(i))) * ymin, y2 + (2 - cos(i)) * ymin, c(y2 + 2 * ymin, 2 * y2 + 2 * ymin), 2 * y2 + 2 * ymin + cos(rev(i)) * ymin) x <- x + xcent y <- y + ycent - ymin - y2 x1 <- cos(theta) * (x - xcent) - sin(theta) * (y - ycent) + xcent y1 <- cos(theta) * (y - ycent) + sin(theta) * (x - xcent) + ycent ##For grid library: if(grid){ grid.lines(unit(x1,"npc"), unit(y1,"npc"),gp=gpar(col=col,lwd=lwd)) } ##Uncomment for base graphics else{ par(xpd=TRUE) points(x1,y1,type='l',col=col,lwd=lwd) par(xpd=FALSE) } } library(ggplot2) x <- c(runif(10),runif(10)+2) y <- c(runif(10),runif(10)+2) qplot(x=x,y=y) + scale_x_continuous("",breaks=c(.5,2.5),labels=c("Low types","High types") ) curly(N=100,Tilt=0.4,Long=0.3,scale=0.025,xcent=0.2525, ycent=par()$usr[3]+0.1,theta=-pi/2,col="red",lwd=2,grid=TRUE) curly(N=100,Tilt=0.4,Long=0.3,scale=0.025,xcent=0.8, ycent=par()$usr[3]+0.1,theta=-pi/2,col="red",lwd=2,grid=TRUE) 

lote de resultados

Aqui está a solução kludgy em ggplot que constrói um desenho de linha que lembra vagamente um ggplot .

Construa uma function que tome como input a posição e as dimensões de uma chave. O que essa function faz é especificar as coordenadas de um desenho de contorno de um colchete e usar algum dimensionamento matemático para obtê-lo no tamanho e posição desejados. Você pode usar este princípio e modificar as coordenadas para obter qualquer forma desejada. Em princípio, você pode usar o mesmo conceito e adicionar curvas, elipses, etc.

 bracket <- function(x, width, y, height){ data.frame( x=(c(0,1,4,5,6,9,10)/10-0.5)*(width) + x, y=c(0,1,1,2,1,1,0)/2*(height) + y ) } 

Passe isso para ggplot e especificamente geom_line

 qplot(x=x,y=y) + scale_x_continuous("",breaks=c(.5,2.5), labels=c("Low types","High types")) + geom_line(data=bracket(0.5,1,0,-0.2)) + geom_line(data=bracket(2.5,2,0,-0.2)) 

insira a descrição da imagem aqui

como @ user697473 sugeriu pBrackets é a solução elegante.

Ele funciona melhor com os comandos de plotagem padrão, mas para fazê-lo funcionar com o GGplot2, use o pBracket::grid.brackets . Estou incluindo o código para facilitar a experimentação.

Começando com o seu código ..

 library(ggplot2) x <- c(runif(10),runif(10)+2) y <- c(runif(10),runif(10)+2) qplot(x=x,y=y) + scale_x_continuous("",breaks=c(.5,2.5),labels=c("Low types","High types") ) + theme(axis.ticks = element_blank()) 

a última linha remove os carrapatos que você não queria.
Agora os pBrackets

 library(pBrackets) # this will also load grid package grid.locator(unit="native") 

Agora, usando o cursor, identifique o ponto no gráfico onde os colchetes começam e terminam. Você obterá as coordenadas correspondentes na unidade 'nativa'. agora alimente-os no comando abaixo

 grid.brackets(240, 440, 50, 440, lwd=2, col="red") grid.brackets(570, 440, 381, 440, lwd=2, col="red") 

Você pode adicionar os colchetes em qualquer lugar no gráfico ou até mesmo adicionar texto usando grid.text .

insira a descrição da imagem aqui

Espero que isto ajude! Obrigado pBrackets !

Pankil!

O novo pacote de pbrackets pode ajudar: http://cran.r-project.org/web/packages/pBrackets/index.html .