I have created a graph in ggplot2 that looks like this:
我在ggplot2中创建了一个这样的图:
depth = c(1.6,2.6,3.6, 4.6,5.6,6.6,7.6,8.6)
ri <- c(0.790143779,1.485888068,2.682375391,1.728120227,0.948414515,71.43308158,4.416120653,0.125458801)
df = data.frame(depth,ri)
library(ggplot2)
m <- qplot(ri, depth, data=df)
m +
scale_x_log10("Richardson Number",breaks = c(0.1,0.25,0.5,1,5,10, 50)) +
scale_y_reverse("Depth (m)")
This is the output:
这是输出:
What I am trying to do is have the x-axis along the top, and also include a geom_line like the one I have added here (manually in Paint).
我要做的是沿着顶部的x轴,并包括一个像我在这里添加的一样的geom_line(手工添加到Paint中)。
I understand that it is difficult to get ggplot2 to move the axes around, and I have tried to reproduce this graph in ggvis but I am unable to get the log10 scale I need. Is there any way I can use R to create the graph I am aiming for?
我知道很难让ggplot2移动坐标轴,我尝试在ggvis中复制这个图形,但是我无法得到我需要的log10刻度。有什么方法可以用R来创建我想要的图吗?
1 个解决方案
#1
3
Updated solution
更新的解决方案
As of ggplot 2.2.0, axes can be drawn on the top of the panel (and/or on the right of the panel)
在ggplot 2.2.0中,可以在面板的顶部绘制坐标轴(以及/或在面板右侧)
library(ggplot2)
depth = c(1.6,2.6,3.6, 4.6,5.6,6.6,7.6,8.6)
ri <- c(0.790143779,1.485888068,2.682375391,1.728120227,0.948414515,71.43308158,4.416120653,0.125458801)
df = data.frame(depth,ri)
m <- qplot(ri, depth, data=df) +
scale_x_log10("Richardson Number",breaks = c(0.1,0.25,0.5,1,5,10, 50),
position = "top") +
scale_y_reverse("Depth (m)")+
geom_path()
Original solution The original, after a little updating to ggplot version2.2.0.
原始的解决方案,在对ggplot version2.2.0进行了一点更新之后。
Axes can be moved around using gtable
functions. Adapting code from @Walter's answer here, the basic idea is to: get the axis (the axis text and the tick marks); reverse the axis text and tick marks; add a new row to the gtable layout immediately above the plot panel; insert the modified axis into the new row.
可以使用gtable函数移动坐标轴。根据@Walter的回答改编代码,基本思想是:获取轴(轴文本和标记);反向轴文字和勾号;在靠近绘图面板的gtable布局上添加新行;将修改后的轴插入到新行中。
library(ggplot2)
library(gtable)
library(grid)
depth = c(1.6,2.6,3.6, 4.6,5.6,6.6,7.6,8.6)
ri <- c(0.790143779,1.485888068,2.682375391,1.728120227,0.948414515,71.43308158,4.416120653,0.125458801)
df = data.frame(depth,ri)
m <- qplot(ri, depth, data=df) +
scale_x_log10("Richardson Number",breaks = c(0.1,0.25,0.5,1,5,10, 50)) +
scale_y_reverse("Depth (m)")+
geom_path()
# Get ggplot grob
g1 <- ggplotGrob(m)
## Get the position of the plot panel in g1
pp <- c(subset(g1$layout, name == "panel", se = t:r))
# Title grobs have margins.
# The margins need to be swapped.
# Function to swap margins -
# taken from the cowplot package:
# https://github.com/wilkelab/cowplot/blob/master/R/switch_axis.R
vinvert_title_grob <- function(grob) {
heights <- grob$heights
grob$heights[1] <- heights[3]
grob$heights[3] <- heights[1]
grob$vp[[1]]$layout$heights[1] <- heights[3]
grob$vp[[1]]$layout$heights[3] <- heights[1]
grob$children[[1]]$hjust <- 1 - grob$children[[1]]$hjust
grob$children[[1]]$vjust <- 1 - grob$children[[1]]$vjust
grob$children[[1]]$y <- unit(1, "npc") - grob$children[[1]]$y
grob
}
# Get xlab and swap margins
index <- which(g1$layout$name == "xlab-b")
xlab <- g1$grobs[[index]]
xlab <- vinvert_title_grob(xlab)
# Put xlab at the top of g1
g1 <- gtable_add_rows(g1, g1$heights[g1$layout[index, ]$t], pp$t-1)
g1 <- gtable_add_grob(g1, xlab, pp$t, pp$l, pp$t, pp$r, clip = "off", name="topxlab")
# Get x axis (axis line, tick marks and tick mark labels)
index <- which(g1$layout$name == "axis-b")
xaxis <- g1$grobs[[index]]
# Swap axis ticks and tick mark labels
ticks <- xaxis$children[[2]]
ticks$heights <- rev(ticks$heights)
ticks$grobs <- rev(ticks$grobs)
# Move tick marks
# Get tick mark length
plot_theme <- function(p) {
plyr::defaults(p$theme, theme_get())
}
tml <- plot_theme(m)$axis.ticks.length # Tick mark length
ticks$grobs[[2]]$y <- ticks$grobs[[2]]$y - unit(1, "npc") + tml
# Swap tick mark labels' margins and justifications
ticks$grobs[[1]] <- vinvert_title_grob(ticks$grobs[[1]])
# Put ticks and tick mark labels back into xaxis
xaxis$children[[2]] <- ticks
# Add axis to top of g1
g1 <- gtable_add_rows(g1, g1$heights[g1$layout[index, ]$t], pp$t)
g1 <- gtable_add_grob(g1, xaxis, pp$t+1, pp$l, pp$t+1, pp$r, clip = "off", name = "axis-t")
# Remove original x axis and xlab
g1 = g1[-c(9,10), ]
# Draw it
grid.newpage()
grid.draw(g1)
#1
3
Updated solution
更新的解决方案
As of ggplot 2.2.0, axes can be drawn on the top of the panel (and/or on the right of the panel)
在ggplot 2.2.0中,可以在面板的顶部绘制坐标轴(以及/或在面板右侧)
library(ggplot2)
depth = c(1.6,2.6,3.6, 4.6,5.6,6.6,7.6,8.6)
ri <- c(0.790143779,1.485888068,2.682375391,1.728120227,0.948414515,71.43308158,4.416120653,0.125458801)
df = data.frame(depth,ri)
m <- qplot(ri, depth, data=df) +
scale_x_log10("Richardson Number",breaks = c(0.1,0.25,0.5,1,5,10, 50),
position = "top") +
scale_y_reverse("Depth (m)")+
geom_path()
Original solution The original, after a little updating to ggplot version2.2.0.
原始的解决方案,在对ggplot version2.2.0进行了一点更新之后。
Axes can be moved around using gtable
functions. Adapting code from @Walter's answer here, the basic idea is to: get the axis (the axis text and the tick marks); reverse the axis text and tick marks; add a new row to the gtable layout immediately above the plot panel; insert the modified axis into the new row.
可以使用gtable函数移动坐标轴。根据@Walter的回答改编代码,基本思想是:获取轴(轴文本和标记);反向轴文字和勾号;在靠近绘图面板的gtable布局上添加新行;将修改后的轴插入到新行中。
library(ggplot2)
library(gtable)
library(grid)
depth = c(1.6,2.6,3.6, 4.6,5.6,6.6,7.6,8.6)
ri <- c(0.790143779,1.485888068,2.682375391,1.728120227,0.948414515,71.43308158,4.416120653,0.125458801)
df = data.frame(depth,ri)
m <- qplot(ri, depth, data=df) +
scale_x_log10("Richardson Number",breaks = c(0.1,0.25,0.5,1,5,10, 50)) +
scale_y_reverse("Depth (m)")+
geom_path()
# Get ggplot grob
g1 <- ggplotGrob(m)
## Get the position of the plot panel in g1
pp <- c(subset(g1$layout, name == "panel", se = t:r))
# Title grobs have margins.
# The margins need to be swapped.
# Function to swap margins -
# taken from the cowplot package:
# https://github.com/wilkelab/cowplot/blob/master/R/switch_axis.R
vinvert_title_grob <- function(grob) {
heights <- grob$heights
grob$heights[1] <- heights[3]
grob$heights[3] <- heights[1]
grob$vp[[1]]$layout$heights[1] <- heights[3]
grob$vp[[1]]$layout$heights[3] <- heights[1]
grob$children[[1]]$hjust <- 1 - grob$children[[1]]$hjust
grob$children[[1]]$vjust <- 1 - grob$children[[1]]$vjust
grob$children[[1]]$y <- unit(1, "npc") - grob$children[[1]]$y
grob
}
# Get xlab and swap margins
index <- which(g1$layout$name == "xlab-b")
xlab <- g1$grobs[[index]]
xlab <- vinvert_title_grob(xlab)
# Put xlab at the top of g1
g1 <- gtable_add_rows(g1, g1$heights[g1$layout[index, ]$t], pp$t-1)
g1 <- gtable_add_grob(g1, xlab, pp$t, pp$l, pp$t, pp$r, clip = "off", name="topxlab")
# Get x axis (axis line, tick marks and tick mark labels)
index <- which(g1$layout$name == "axis-b")
xaxis <- g1$grobs[[index]]
# Swap axis ticks and tick mark labels
ticks <- xaxis$children[[2]]
ticks$heights <- rev(ticks$heights)
ticks$grobs <- rev(ticks$grobs)
# Move tick marks
# Get tick mark length
plot_theme <- function(p) {
plyr::defaults(p$theme, theme_get())
}
tml <- plot_theme(m)$axis.ticks.length # Tick mark length
ticks$grobs[[2]]$y <- ticks$grobs[[2]]$y - unit(1, "npc") + tml
# Swap tick mark labels' margins and justifications
ticks$grobs[[1]] <- vinvert_title_grob(ticks$grobs[[1]])
# Put ticks and tick mark labels back into xaxis
xaxis$children[[2]] <- ticks
# Add axis to top of g1
g1 <- gtable_add_rows(g1, g1$heights[g1$layout[index, ]$t], pp$t)
g1 <- gtable_add_grob(g1, xaxis, pp$t+1, pp$l, pp$t+1, pp$r, clip = "off", name = "axis-t")
# Remove original x axis and xlab
g1 = g1[-c(9,10), ]
# Draw it
grid.newpage()
grid.draw(g1)