ggplot2: фигурные скобки на оси?

Отвечая на недавний вопрос визуализации, мне действительно нужны скобки, чтобы показать пролет на оси, и я не могу понять, как это сделать в ggplot2. Вот сюжет:

пример участка

Вместо метки, мне бы очень хотелось, чтобы метка оси y «Вторая буква двухбуквенных имен» имела скобу, простирающуюся от 1 до 10 (вертикальный интервал красных и синих вторых букв). Но я не уверен, как это сделать. Ось X могла бы выиграть от подобного лечения.

Код доступен в связанном CrossValidated вопросе (и излишне сложный для этого примера, поэтому я его не покажу). Вместо этого вот минимальный пример:

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

минимальный пример

В этом случае скобка из (0,1) для низких типов и из (2,3) для высоких типов была бы идеальной вместо отметок.

Я бы предпочел не использовать geom_rect потому что:

  • Маркировка останется
  • Я бы предпочел скобки
  • Это будет внутри сюжета, а не вне его

Как бы я это сделал? Идеальный ответ:

  • Хорошая, гладкая, тонкая фигурная скобка
  • Выведенный за пределами области печати
  • Определяется с помощью аргумента высокого уровня (в идеале объект типа диапазона, переданный опции breaks в scale_x_continuous )

Обновление. Обязательно ознакомьтесь с этими связанными вопросами и ответами Stackoverflow, если вам нужно сохранить график с помощью ggsave () и сохранить скобки в сохраненном изображении.


ОП запросил кронштейн с участка. Это решение использует axis.ticks.length в сочетании с axis.ticks = element_blank() чтобы скобка была вне области построения графика. Этот ответ основывается на ответах @Pankil и @ user697473: мы будем использовать пакет pBrackets R – и включим картинки!

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

введите описание изображения здесь

Быстрая заметка о ответе @ Панкиля:

 ## 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... 

введите описание изображения здесь

И еще пара демонстрирует функциональность 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") 

введите описание изображения здесь

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

введите описание изображения здесь

Другое решение, использующее функцию, которая рисует фигурную скобку.

Спасибо Гур!

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

график результата

Вот решение kludgy в ggplot которое строит линейный рисунок, который смутно напоминает фигурный скотч.

Постройте функцию, которая принимает в качестве входных данных положение и размеры фигурной скобки. То, что делает эта функция, – это указать координаты контурного чертежа скобки и использовать некоторое математическое масштабирование, чтобы получить размер и желаемую позицию. Вы можете использовать этот принцип и изменить координаты, чтобы дать вам любую желаемую форму. В принципе вы можете использовать ту же концепцию и добавить кривые, эллипсы и т. Д.

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

Передайте это ggplot и, в частности, 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)) 

введите описание изображения здесь

как @ user697473 предложил pBrackets – элегантное решение.

Он лучше всего работает с командами построения по умолчанию, но чтобы он работал с GGplot2, используйте pBracket::grid.brackets . Я включаю код, чтобы упростить его.

Начиная с вашего кода ..

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

в последней строке удаляются тики, которые вам не нужны.
Теперь pBrackets

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

теперь с помощью курсора определите точку на графике, где скобки начинаются и заканчиваются. Вы получите соответствующие координаты в «нативной» единице. теперь подайте их в команду ниже

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

Вы можете добавить скобки в любом месте графика или даже добавить текст, используя grid.text .

введите описание изображения здесь

Надеюсь это поможет! Спасибо, pBrackets !

Pankil!

Новый пакет pbrackets может помочь: http://cran.r-project.org/web/packages/pBrackets/index.html .

  • Совокупное число в R
  • Как просмотреть исходный код для функции?
  • Удалите весь столбец из data.frame в R
  • Увеличить количество тиков оси
  • передать символьные строки в ggplot2 внутри функции
  • Эффективное вычисление линейной комбинации столбцов data.table
  • Заменить значение в кадре данных на основе условного (`if`) оператора
  • R передать переменные столбцы в ggplot2
  • Как можно объединить две строки?
  • ранг и порядок в R
  • Как создать xml из объектов R, например, есть ли функция listToXml?
  • Давайте будем гением компьютера.