Как рисовать линии за пределами участка в ggplot2?

Я создал этот сюжет с ggplot2 :

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

Внешние линии должны соответствовать шкале Y (т. Е. Положение Y строк для Text1 должно быть 100 и 85). Единственный способ, которым я могу это сделать, нарисовать пустой рисунок справа от фигуры с тем же масштабом, что и баррикад, а затем использовать функцию annotations для рисования линий. Другой подход состоит в том, чтобы просто «вручную» провести линии с grid.lines , однако координаты grid.lines не будут соответствовать шкале Y графика.

Можно ли каким-то образом использовать эти линии, используя другой подход? Я предполагаю, что это должно быть сделано с grid.lines . Как я могу передать координаты Y из barchart в grid.lines ?

Ниже приведен минимальный код, используемый для создания этой цифры:

 library (ggplot2) test= data.frame( group=c(rep(1,6), rep(2,6)), subgroup=c( 1,1,1,2,2,2,1,1,1,2,2,2), category=c( rep(1:3, 4)), count=c( 10,80,10,5,90,5, 10,80,10,5,90,5 ) ) qplot(subgroup, count, data=test, geom="bar", stat="identity", fill =category, facets = .~ group, width=0.9)+ opts(legend.position="none", plot.margin = unit(c(0,9,2,0), "lines")) 

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

Как рисовать линии справа от баров?

Недавно я задал вопрос о рисовании текста вне области графика в ggplot2, и решение заключалось в использовании gt$layout и grid.draw .

Отображение текста под графиком, созданным ggplot2

Может ли такой подход использоваться здесь? Я понимаю, что annotation_custom используется только для текста и не будет работать с другими графическими элементами. благодаря

Обновить

В исходном решении используется annotation_custom , но проблема с annotation_custom заключается в том, что он рисует аннотацию во всех панелях. Однако с простой модификацией annotation_custom можно сделать только одну панель (взято из ответа Баптиста здесь )

 annotation_custom2 <- function (grob, xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf, data) { layer(data = data, stat = StatIdentity, position = PositionIdentity, geom = ggplot2:::GeomCustomAnn, inherit.aes = TRUE, params = list(grob = grob, xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax)) } library(ggplot2) library(grid) #Some data test = data.frame( group=c(rep(1,6), rep(2,6)), subgroup=c( 1,1,1,2,2,2,1,1,1,2,2,2), category=c( rep(1:3, 4)), count=c( 10,80,10,5,90,5, 10,80,10,5,90,5 ) ) # base plot p <- ggplot(test) + geom_bar(aes(subgroup, count, fill = category), stat = "identity") + facet_grid(. ~ group) + theme(legend.position = "none", plot.margin = unit(c(1,5,1,1), "lines")) # Create the text Grobs Text1 = textGrob("Text 1") Text2 = textGrob("Text 2") Text4 = textGrob("Text 4") ## Add the annotations # Which panel to attach the annotations data = data.frame(group=2) # Text 1 p1 = p + annotation_custom2(Text1, xmin = 3., xmax = 3., ymin = 85, ymax = 100, data = data) + annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 100, ymax = 100, data = data) + annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 85, ymax = 85, data = data) + annotation_custom2(linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 85, ymax = 100, data = data) # Text 2 p1 = p1 + annotation_custom2(Text2, xmin = 3, xmax = 3, ymin = 20, ymax = 80, data = data) + annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 80, ymax = 80, data = data) + annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 20, ymax = 20, data = data) + annotation_custom2(linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 20, ymax = 80, data = data) # Text 4 p1 = p1 + annotation_custom2(Text4, xmin = 3, xmax = 3, ymin = 0, ymax = 15, data = data) + annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 15, ymax = 15, data = data) + annotation_custom2(linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 0, ymax = 0, data = data) + annotation_custom2(linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 0, ymax = 15, data = data) # Code to override clipping gt <- ggplotGrob(p1) gt$layout[grepl("panel", gt$layout$name), ]$clip <- "off" # Draw the plot grid.newpage() grid.draw(gt) 

Исходное решение

Я думаю, что почти любой Grob, созданный с использованием grid() можно использовать в annotation_custom() . Там могут быть более аккуратные способы сделать это, но вот способ использования grid , annotation_custom и @ baptiste кода здесь, чтобы переопределить отсечение (как в предыдущем сообщении).

 library (ggplot2) library(grid) test= data.frame( group=c(rep(1,6), rep(2,6)), subgroup=c( 1,1,1,2,2,2,1,1,1,2,2,2), category=c( rep(1:3, 4)), count=c( 10,80,10,5,90,5, 10,80,10,5,90,5 ) ) ## EDIT: Updated qplot() command p <- qplot(subgroup, count, data = test, geom = "bar", stat = "identity", fill = category, facets = .~ group, width = 0.9)+ theme(legend.position="none", plot.margin = unit(c(0,9,2,0), "lines")) # Create the text Grobs Text1 = textGrob("Text 1") Text2 = textGrob("Text 2") Text4 = textGrob("Text 4") # Draw the plot # Text 1 p1 = p + annotation_custom(grob = Text1, xmin = 3., xmax = 3., ymin = 85, ymax = 100) + annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 100, ymax = 100) + annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 85, ymax = 85) + annotation_custom(grob = linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 85, ymax = 100) # Text 2 p1 = p1 + annotation_custom(grob = Text2, xmin = 3, xmax = 3, ymin = 20, ymax = 80) + annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 80, ymax = 80) + annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 20, ymax = 20) + annotation_custom(grob = linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 20, ymax = 80) # Text 4 p1 = p1 + annotation_custom(grob = Text4, xmin = 3, xmax = 3, ymin = 0, ymax = 15) + annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 15, ymax = 15) + annotation_custom(grob = linesGrob(), xmin = 2.6, xmax = 2.75, ymin = 0, ymax = 0) + annotation_custom(grob = linesGrob(), xmin = 2.75, xmax = 2.75, ymin = 0, ymax = 15) p1 # Code to override clipping gt <- ggplot_gtable(ggplot_build(p1)) gt$layout$clip[gt$layout$name=="panel"] <- "off" grid.draw(gt) 

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

Я добавил строки / текст, используя код по этой ссылке: Использование grconvertX / grconvertY в ggplot2 . Этот подход использует grid.text и grid.lines вместо grobs. Я не уверен, какой подход лучше.

Я думаю, grid.lines можно объединить в оператор grid.polyline или, возможно, сделать через цикл. Положения x и y могут быть установлены на одну переменную вместо жесткого кодирования в каждой строке.

Единственное возможное осложнение – передать масштаб в окно просмотра. Однако, пока тот же масштаб используется в GGPLOT и в окне просмотра, этот код должен работать. Обратите внимание, что область просмотра использует всю высоту графика от 0 до 100.

 library (ggplot2) library(grid) library(gridBase) test= data.frame( group=c(rep(1,6), rep(2,6)), subgroup=c( 1,1,1,2,2,2,1,1,1,2,2,2), category=c( rep(1:3, 4)), count=c( 10,80,10,5,90,5, 10,80,10,5,90,5 ) ) qplot(subgroup, count, data=test, geom="bar", stat="identity", fill =category, facets = .~ group, width=0.9)+ opts(legend.position="none", plot.margin = unit(c(0,9,2,0), "lines")) current.vpTree() downViewport('panel-4-6') pushViewport(dataViewport( yscale=c(0,100), clip='off',xscale=c(0,1))) grid.text(x=1.21, y = 90, default.units='native' ,label="Text 1") grid.text(x=1.21, y = 55, default.units='native' ,label="Text 2") grid.text(x=1.21, y = 10, default.units='native' ,label="Text 3") grid.lines(x=c(1.02,1.12), y = c(95,95), default.units='native' ) grid.lines(x=c(1.02,1.12), y = c(85, 85), default.units='native' ) grid.lines(x=c(1.12,1.12), y = c(85, 95), default.units='native' ) grid.lines(x=c(1.02,1.12), y = c(80, 80), default.units='native' ) grid.lines(x=c(1.02,1.12), y = c(20, 20), default.units='native' ) grid.lines(x=c(1.12,1.12), y = c(80, 20), default.units='native' ) grid.lines(x=c(1.02,1.12), y = c(5, 5), default.units='native' ) grid.lines(x=c(1.02,1.12), y = c(15, 15), default.units='native' ) grid.lines(x=c(1.12,1.12), y = c(5, 15), default.units='native' ) 

Извиняюсь за любые проблемы с форматированием – я просто вставлял свой код и использовал кнопку кода для отступов.

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

Обновленные opts устарели; вместо этого используйте theme .

Вот еще одно решение. Он обходит проблему annotation_custom() рисования грыз в обеих панелях. Он рисует два графика: первый – ваш график; второй содержит только annotations. Затем они объединяются с помощью grid.arrange() из пакета gridExtra . Однако проблема с полилинией остается.

По-прежнему остается вопрос о том, чтобы шкалы оси Y были одинаковыми на двух графиках. Но с осторожностью это можно сделать. На графике, содержащем annotations, обратите внимание, что элементы, которые могут повлиять на масштаб оси y, не удаляются (через theme_blank() , а скорее скрыты (с использованием colour = NA ).

 library(ggplot2) library(gridExtra) library(grid) test= data.frame( group=c(rep(1,6), rep(2,6)), subgroup=c( 1,1,1,2,2,2,1,1,1,2,2,2), category=c( rep(1:3, 4)), count=c( 10,80,10,5,90,5, 10,80,10,5,90,5)) # The bar plot p1 <- ggplot(test, aes(subgroup, count, fill = category)) + geom_bar(stat = "identity") + facet_grid(.~ group) + theme(legend.position = "none", plot.margin = unit(c(1,0,2,0), "lines")) p1 <- p1 + ylim(0, 100) # The empty plot to contain the annotations p2 = ggplot(data.frame(x = c(1,2), y = c(0,100), z = c(1,1)), aes(x,y)) + theme_bw() + facet_wrap(~ z) + theme(axis.title.y = element_blank(), axis.title.x = element_text(colour = NA), axis.text.y = element_blank(), axis.text.x = element_text(colour = NA), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.ticks = element_line(colour = NA), panel.border = element_rect(colour = NA), strip.background = element_rect(colour = NA, fill = NA), strip.text.x = element_text(colour = NA), plot.margin = unit(c(1,0,2,0), "lines")) # The annotations Text1 = textGrob("Text 1") Text2 = textGrob("Text 2") Text4 = textGrob("Text 4") p2 = p2 + annotation_custom(grob = Text1, xmin = 1.4, xmax = 1.4, ymin = 85, ymax = 100) + annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 100, ymax = 100) + annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 85, ymax = 85) + annotation_custom(grob = linesGrob(), xmin = 1.1, xmax = 1.1, ymin = 85, ymax = 100) p2 = p2 + annotation_custom(grob = Text2, xmin = 1.4, xmax = 1.4, ymin = 20, ymax = 80) + annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 80, ymax = 80) + annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 20, ymax = 20) + annotation_custom(grob = linesGrob(), xmin = 1.1, xmax = 1.1, ymin = 20, ymax = 80) p2 = p2 + annotation_custom(grob = Text4, xmin = 1.4, xmax = 1.4, ymin = 0, ymax = 15) + annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 15, ymax = 15) + annotation_custom(grob = linesGrob(), xmin = 1, xmax = 1.1, ymin = 0, ymax = 0) + annotation_custom(grob = linesGrob(), xmin = 1.1, xmax = 1.1, ymin = 0, ymax = 15) # Putting the two plots together plot = arrangeGrob(p1, p2, ncol = 2, widths = unit(c(10, 2), c("null", "null"))) grid.draw(plot) 

бот

  • Как заставить R использовать указанный факторный уровень в качестве ссылки в регрессии?
  • Список всех файлов, соответствующих шаблону полного пути в R
  • Выходной журнал ошибок / предупреждений (txt-файл) при запуске R-скрипта в командной строке
  • Текущая дата YAML в rmarkdown
  • Подсчитайте количество нhive в строке и удалите строки с более чем n нулями
  • избегайте строки, напечатанной на консоли, усеченной (в RStudio)
  • Наложение двух графиков ggplot2 stat_density2d с альфа-каналами
  • Последнее наблюдение перенесено вперед В кадре данных?
  • Как найти общие элементы из нескольких векторов?
  • Развернуть диапазоны, определенные столбцами «от» и «до»
  • R управления памятью / не может выделить вектор размера n Mb
  • Давайте будем гением компьютера.