我需要在一个图表中绘制一个显示计数的柱状图和一个显示率的折线图,我可以分别做这两个,但当我把它们放在一起时,我的第一层(即geom_bar)的比例被第二层(即geom_line)重叠。

我可以将geom_line的轴向右移动吗?


当前回答

下面的文章帮助我将ggplot2生成的两个图合并到单行上:

一页上的多个图(ggplot2)由Cookbook for R

下面是代码在这种情况下的样子:

p1 <- 
  ggplot() + aes(mns)+ geom_histogram(aes(y=..density..), binwidth=0.01, colour="black", fill="white") + geom_vline(aes(xintercept=mean(mns, na.rm=T)), color="red", linetype="dashed", size=1) +  geom_density(alpha=.2)

p2 <- 
  ggplot() + aes(mns)+ geom_histogram( binwidth=0.01, colour="black", fill="white") + geom_vline(aes(xintercept=mean(mns, na.rm=T)), color="red", linetype="dashed", size=1)  

multiplot(p1,p2,cols=2)

其他回答

您可以创建一个缩放因子,应用于第二个geom和右y轴。这是从塞巴斯蒂安的解推导出来的。

library(ggplot2)

scaleFactor <- max(mtcars$cyl) / max(mtcars$hp)

ggplot(mtcars, aes(x=disp)) +
  geom_smooth(aes(y=cyl), method="loess", col="blue") +
  geom_smooth(aes(y=hp * scaleFactor), method="loess", col="red") +
  scale_y_continuous(name="cyl", sec.axis=sec_axis(~./scaleFactor, name="hp")) +
  theme(
    axis.title.y.left=element_text(color="blue"),
    axis.text.y.left=element_text(color="blue"),
    axis.title.y.right=element_text(color="red"),
    axis.text.y.right=element_text(color="red")
  )

注意:使用ggplot2 v3.0.0

常见的用例有双y轴,例如,显示每月温度和降水的气体图。这里是一个简单的解决方案,从威震天的解决方案中推广,允许你设置变量的下限为零:

示例数据:

climate <- tibble(
  Month = 1:12,
  Temp = c(-4,-4,0,5,11,15,16,15,11,6,1,-3),
  Precip = c(49,36,47,41,53,65,81,89,90,84,73,55)
  )

将以下两个值设置为接近数据限制的值(您可以使用这些值来调整图形的位置;坐标轴仍然是正确的):

ylim.prim <- c(0, 180)   # in this example, precipitation
ylim.sec <- c(-4, 18)    # in this example, temperature

下面根据这些极限进行必要的计算,并制作出图本身:

b <- diff(ylim.prim)/diff(ylim.sec)
a <- ylim.prim[1] - b*ylim.sec[1]) # there was a bug here

ggplot(climate, aes(Month, Precip)) +
  geom_col() +
  geom_line(aes(y = a + Temp*b), color = "red") +
  scale_y_continuous("Precipitation", sec.axis = sec_axis(~ (. - a)/b, name = "Temperature")) +
  scale_x_continuous("Month", breaks = 1:12) +
  ggtitle("Climatogram for Oslo (1961-1990)")  

如果你想确保红线对应右边的y轴,你可以在代码中添加一个主题句:

ggplot(climate, aes(Month, Precip)) +
  geom_col() +
  geom_line(aes(y = a + Temp*b), color = "red") +
  scale_y_continuous("Precipitation", sec.axis = sec_axis(~ (. - a)/b, name = "Temperature")) +
  scale_x_continuous("Month", breaks = 1:12) +
  theme(axis.line.y.right = element_line(color = "red"), 
        axis.ticks.y.right = element_line(color = "red"),
        axis.text.y.right = element_text(color = "red"), 
        axis.title.y.right = element_text(color = "red")
        ) +
  ggtitle("Climatogram for Oslo (1961-1990)")

右轴的颜色:

我发现这个答案对我帮助最大,但发现有一些边缘情况,它似乎不能正确处理,特别是消极的情况,以及极限距离为0的情况(如果我们从最大/最小数据中获取极限,就会发生这种情况)。测试似乎表明,这是一致的

我使用以下代码。这里我假设我们有[x1,x2]我们想把它变换成[y1,y2]。我处理这个问题的方法是将[x1,x2]转换为[0,1](一个足够简单的转换),然后[0,1]转换为[y1,y2]。

climate <- tibble(
  Month = 1:12,
  Temp = c(-4,-4,0,5,11,15,16,15,11,6,1,-3),
  Precip = c(49,36,47,41,53,65,81,89,90,84,73,55)
)
#Set the limits of each axis manually:

  ylim.prim <- c(0, 180)   # in this example, precipitation
ylim.sec <- c(-4, 18)    # in this example, temperature



  b <- diff(ylim.sec)/diff(ylim.prim)

#If all values are the same this messes up the transformation, so we need to modify it here
if(b==0){
  ylim.sec <- c(ylim.sec[1]-1, ylim.sec[2]+1)
  b <- diff(ylim.sec)/diff(ylim.prim)
}
if (is.na(b)){
  ylim.prim <- c(ylim.prim[1]-1, ylim.prim[2]+1)
  b <- diff(ylim.sec)/diff(ylim.prim)
}


ggplot(climate, aes(Month, Precip)) +
  geom_col() +
  geom_line(aes(y = ylim.prim[1]+(Temp-ylim.sec[1])/b), color = "red") +
  scale_y_continuous("Precipitation", sec.axis = sec_axis(~((.-ylim.prim[1]) *b  + ylim.sec[1]), name = "Temperature"), limits = ylim.prim) +
  scale_x_continuous("Month", breaks = 1:12) +
  ggtitle("Climatogram for Oslo (1961-1990)")  

这里的关键部分是,我们用~((.-ylim.prim[1]) *b + ylim.sec[1])转换次要y轴,然后对实际值y = ylim.prim[1]+(Temp-ylim.sec[1])/b)应用逆。我们还应该确保limits = ylim.prim。

我承认并同意哈德利(和其他人)的观点,即单独的y量表“存在根本缺陷”。说到这里,我经常希望ggplot2有这个特性——特别是当数据是宽格式的,并且我想快速地可视化或检查数据时(即仅供个人使用)。

虽然tidyverse库可以很容易地将数据转换为长格式(这样facet_grid()就可以工作),但这个过程仍然不是简单的,如下所示:

library(tidyverse)
df.wide %>%
    # Select only the columns you need for the plot.
    select(date, column1, column2, column3) %>%
    # Create an id column – needed in the `gather()` function.
    mutate(id = n()) %>%
    # The `gather()` function converts to long-format. 
    # In which the `type` column will contain three factors (column1, column2, column3),
    # and the `value` column will contain the respective values.
    # All the while we retain the `id` and `date` columns.
    gather(type, value, -id, -date) %>%
    # Create the plot according to your specifications
    ggplot(aes(x = date, y = value)) +
        geom_line() +
        # Create a panel for each `type` (ie. column1, column2, column3).
        # If the types have different scales, you can use the `scales="free"` option.
        facet_grid(type~., scales = "free")

从ggplot2 2.2.0开始,您可以添加如下的辅助轴(取自ggplot2 2.2.0公告):

ggplot(mpg, aes(displ, hwy)) + 
  geom_point() + 
  scale_y_continuous(
    "mpg (US)", 
    sec.axis = sec_axis(~ . * 1.20, name = "mpg (UK)")
  )