在刻面ggplot中自动执行tick max和min

时间:2016-03-10 17:22:02

标签: r ggplot2

我试图在刻面的ggplot中标记每个x轴的最大值和最小值。我有几个具有不同x刻度和相同y刻度的刻面,x轴刻度标签相互重叠。我不是必须手动确定每个方面x轴的限制和中断,而是寻找一种方法来标记每个方面的最小值和最大值。

使用CO2数据集的示例数据的代码(请参阅?CO2):

CO2$num <- 1:nrow(CO2)
library(reshape2)
CO2.melt <- melt(CO2,
                 id.var=c("Type",
                          "Plant",
                          "Treatment",
                          "num"))
CO2.melt <- CO2.melt[order(CO2.melt$num),]

library(ggplot2)
ggplot(CO2.melt, 
       aes(x = value, 
           y = num)) +
  geom_path(aes(color = Treatment)) +
  facet_wrap( ~ variable, scales = "free_x",nrow=1)

enter image description here

目的是复制日志显示,例如this one

2 个答案:

答案 0 :(得分:8)

如果要为tick标签实现此功能,则在分面图中使用scales = "free_x"会使此操作很难实现自动化。但是,通过一些修补和其他几个软件包的帮助,您还可以使用以下方法:

1)汇总数据,以便了解x轴上需要的标签/符号:

library(data.table)
minmax <- melt(setDT(CO2.melt)[, .(min.val = min(value), max.val = max(value),
                                   floor.end = 10*ceiling(min(value)/10),
                                   ceil.end = 10*floor((max(value)-1)/10)),
                               variable][],
               measure.vars = patterns('.val','.end'),
               variable.name = 'var',
               value.name = c('minmax','ends'))

给出:

> minmax
   variable var minmax ends
1:     conc   1   95.0  100
2:   uptake   1    7.7   10
3:     conc   2 1000.0  990
4:   uptake   2   45.5   40

2)为每个方面创建休息时间:

brks1 <- c(95,250,500,750,1000)
brks2 <- c(7.7,10,20,30,40,45.5)

3)创建构面:

p1 <- ggplot(CO2.melt[CO2.melt$variable=="conc",], 
             aes(x = value, y = num, colour = Treatment)) +
  geom_path() +
  scale_x_continuous(breaks = brks1) +
  theme_minimal(base_size = 14) +
  theme(axis.text.x = element_text(colour = c('red','black')[c(1,2,2,2,1)],
                                   face = c('bold','plain')[c(1,2,2,2,1)]),
        axis.title = element_blank(),
        panel.grid.major = element_line(colour = "grey60"),
        panel.grid.minor = element_blank())

p2 <- ggplot(CO2.melt[CO2.melt$variable=="uptake",], 
             aes(x = value, y = num, colour = Treatment)) +
  geom_path() +
  scale_x_continuous(breaks = brks2) +
  theme_minimal(base_size = 14) +
  theme(axis.text.x = element_text(colour = c('red','black')[c(1,2,2,2,2,1)],
                                   face = c('bold','plain')[c(1,2,2,2,2,1)]),
        axis.title = element_blank(),
        panel.grid.major = element_line(colour = "grey60"),
        panel.grid.minor = element_blank())

4)将图例提取到单独的对象中:

library(grid)
library(gtable)
fill.legend <- gtable_filter(ggplot_gtable(ggplot_build(p2)), "guide-box")
legGrob <- grobTree(fill.legend)

5)创建最终的情节:

library(gridExtra)
grid.arrange(p1 + theme(legend.position="none"), 
             p2 + theme(legend.position="none"), 
             legGrob, ncol=3, widths = c(4,4,1))

导致:

enter image description here

自动执行此操作的可能替代解决方案是使用geom_textgeom_label。一个示例,说明如何实现这一目标:

# create a summary
library(dplyr)
library(tidyr)
minmax <- CO2.melt %>% 
  group_by(variable) %>% 
  summarise(minx = min(value), maxx = max(value)) %>%
  gather(lbl, val, -1)

# create the plot
ggplot(CO2.melt, aes(x = value, y = num, color = Treatment)) +
  geom_path() +
  geom_text(data = minmax, 
            aes(x = val, y = -3, label = val), 
            colour = "red", fontface = "bold", size = 5) +
  facet_wrap( ~ variable, scales = "free_x", nrow=1) +
  theme_minimal()

给出:

enter image description here

您还可以在ggplot内动态获取最小值和最大值(信用额度为@eipi10)。另一个使用geom_label的例子:

ggplot(CO2.melt, aes(x = value, y = num, color = Treatment)) +
  geom_path() +
  geom_label(data = CO2.melt %>% 
               group_by(variable) %>% 
               summarise(minx = min(value), maxx = max(value)) %>%
               gather(lbl, val, -1), 
             aes(x = val, y = -3, label = val), 
             colour = "red", fontface = "bold", size = 5) +
  facet_wrap( ~ variable, scales = "free_x", nrow=1) +
  theme_minimal()

给出:

enter image description here

答案 1 :(得分:5)

修改更新至ggplot2 ver 3.0.0

此方法修改ggplot构建数据中的标签(即<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>)。我已经删除了x轴扩展,以便最大值和最小值落在面板边界上。

ggplot_build(plot)

enter image description here