Двойная ось Y — метки и фоновые линии сетки правой оси Y

Мне нужно сделать двойную ось Y в ggplot2. Я попытался следовать решению @kohske, опубликованному здесь: http://rpubs.com/kohske/dual_axis_in_ggplot2 Однако две вещи по-прежнему нежелательны, и я не могу понять, как их решить. 1. На графике ниже метка правой оси y отсутствует, а я хочу, чтобы она присутствовала 2. линии сетки для правой оси y показаны поверх гистограммы, в то время как она должна быть на заднем плане. Вот сюжет:

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

и код:

library(ggplot2)
library(grid)
library(gtable)

grid.newpage()
p1 <- ggplot(ex, 
         aes(factor(subgroups, levels = c('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 
                                          'Saturday', 'Sunday')),
             y_left)) + 
  geom_bar(fill = rgb(16/255, 72/255, 128/255), stat = 'identity') + 
  theme_bw() +
  labs(x = 'weekday')
p2 <- ggplot(ex, aes(factor(subgroups,
                              levels = c('Monday', 'Tuesday', 'Wednesday', 
                                         'Thursday', 'Friday', 'Saturday', 'Sunday')), y_right)) + 
  geom_line(colour = rgb(237/255, 165/255, 6/255), group = 1) + 
  geom_point(color = rgb(237/255, 165/255, 6/255), size = 3) +
  scale_y_continuous(limits = c(0, 180)) +
  labs(y = 'name for y_left axis') +
  theme_bw() %+replace% 
  theme(panel.background = element_rect(fill = NA))
# extract gtable
g1 <- ggplot_gtable(ggplot_build(p1))
g2 <- ggplot_gtable(ggplot_build(p2))

# overlap the panel of 2nd plot on that of 1st plot
pp <- c(subset(g1$layout, name == "panel", se = t:r))
g <- gtable_add_grob(g1, g2$grobs[[which(g2$layout$name == "panel")]], pp$t, 
                 pp$l, pp$b, pp$l)

# axis tweaks
ia <- which(g2$layout$name == "axis-l")
ga <- g2$grobs[[ia]]
ax <- ga$children[[2]]
ax$widths <- rev(ax$widths)
ax$grobs <- rev(ax$grobs)
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm")
g <- gtable_add_cols(g, g2$widths[g2$layout[ia, ]$l], length(g$widths) - 1)
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b)

# draw it
grid.draw(g)

person jakes    schedule 04.09.2018    source источник
comment
Вам не нужно делать это таким образом. Некоторое время назад они добавили опцию вторичной оси в ggplot. Попробуйте поместить оба geom на один график и добавить scale_y_continuous(sec.axis = sec_axis(~.-280), name = "2nd axis name"). Возможно, вам придется скорректировать формулу, чтобы все выровнялось по желанию.   -  person MDK    schedule 04.09.2018


Ответы (1)


Некоторое время назад они добавили опцию вторичной оси в ggplot. Попробуйте поместить оба geom на один график и добавить scale_y_continuous(sec.axis = sec_axis(~.-280), name = "My Second Axis").

Вместо простого вычитания вы можете вычислить отношение. Это можно сделать встроенным, используя что-то вроде sec.axis = sec_axis(~. * max(myData$y) / max(myData$y2)), или вы можете вычислить его заранее и применить как ко 2-й оси, так и к данным, которые вы собираетесь читать на второй оси, например так:

library(ggplot2)
# Create Sample Data
myData <- data.frame(x = seq(1, 10, length.out = 10), 
                     y = seq(0, 20, length.out = 10), 
                     y2 = seq(0, 100, length.out = 10))
myData.ratio <- max(myData$y) / max(myData$y2)
ggplot(myData, (aes(x=x, y=y))) +
    geom_bar(stat="identity", aes(y=y2 * myData.ratio), fill = "lightblue") +
    geom_line(color="red") +
    geom_point(color="red") +
    scale_y_continuous(sec.axis = sec_axis(~. / myData.ratio, name = "My Second Axis"))

Обратите внимание, что мы умножаем фактические значения на отношение в geom и делим на него при вычислении оси.

Выход:

Двухосевой выход

person MDK    schedule 04.09.2018
comment
Можно ли выполнять какие-то вычисления внутри sec_axis? Я имею в виду что-то вроде scale_y_continuous(sec.axis = sec_axis(~. * max(y_left) / max(y_right), name = "2nd axis name") - person jakes; 04.09.2018
comment
Конечно, это работает просто отлично. Я обновлю ответ примером. - person MDK; 04.09.2018