创建自定义几何图形时使用美学为子图着色

时间:2019-07-09 12:52:45

标签: r ggplot2

我正在创建一个自定义几何图形,其中显示了一个小绘图,一个小迷你条形图,可以显示在该图的某处。您将在下面看到一个示例(不要问我为什么这样做,因为原因需要它)。

我的问题:

  • ggplot2如何选择条形的颜色?我看不出它们是如何定义的。当调用coord$transform时,它们神奇地出现。为什么在图的不同部分上,相同柱面编号的颜色不同?
  • 如何使迷你条形图之间的颜色匹配?
  • 如何添加说明条形的图例?我假设必须从geom的设置函数或相关的stat中调用它,因为通常每个组仅获得一个密钥(这里,每个组需要多个密钥)。

示例:使用mpg数据集,绘制随时间变化的平均位移。每年,我们都会绘制一个小条形图,显示具有给定气缸数的汽车的相对比例(尽管仍然在标签上起作用)。

# library(ggplot2)
# library(grid)
## per year summary – mean displacement 
point.data <- mpg %>% group_by(year) %>% summarise(mean_displ=mean(displ))

## per year, number of models with the  given number of cylinders
bar.data <- mpg %>% group_by(year) %>% count(cyl) %>% left_join(point.data)
## position of the mini barplot
bar.data$x <- bar.data$year
bar.data$y <- bar.data$mean_displ + .15

我使用自定义几何图形显示条形图(以下是该几何图形的代码)

ggplot(point.data, aes(x=year, y=mean_displ)) + 
  geom_point(size=8, col="lightblue") + 
  geom_line(size=3, col="lightblue") + 
  geom_bar_widget(data=bar.data, 
     aes(x=x, y=y, width=.2, height=.15, 
         group=year, value=n, fill=factor(n))) + 
  xlim(1995, 2010) + ylim(3, 4)

结果:

enter image description here

这是geom的代码:

## calculate the mini barplot
.bar_widget_bars <- function(x, y, w, h, v, fill) {

     nv <- length(v)
     v <- h * v / max(v)  # scale the values

     dx <- w / nv         # width of a bar

     # xx and yy are the mid positions of the rectangles
     xx <- x - w/2 + seq(dx/2, w - dx/2, length.out=nv)
     yy <- y - h/2 + v/2

     ## widths and heights of the rectangles
     ww <- rep(dx, nv)
     hh <- v

     list(rectGrob(xx, yy, ww, hh, gp=gpar(fill=fill)))
}


## draw a mini barplot
.bar_widget_draw_group <- function(data, panel_params, coord, wgdata) {

     ct <- coord$transform(data, panel_params)

     grobs <- .bar_widget_bars(x=ct$x[1], y=ct$y[1], 
                               w=ct$width[1], h=ct$height[1], 
                               v=data$value, fill=ct$fill)

     class(grobs) <- "gList"
     gTree("bar_widget_grob", children=grobs)
}

## the widget for the mini barplot
GeomBarWidget <- ggproto("GeomPieWidget",
  Geom,
  required_aes=c("x", "y", "width", "height", "group", "value"),
  default_aes=aes(shape=19, colour="black", fill=NULL, labels=NULL),
  draw_key=draw_key_blank(),
  draw_group=.bar_widget_draw_group,
  extra_params=c("na.rm")
)

geom_bar_widget <- function(mapping = NULL, data = NULL, 
                              stat = "identity",
                              position = "identity", na.rm = FALSE,
                              show.legend = FALSE,
                              inherit.aes = TRUE, ...) {
  layer(
    geom = GeomBarWidget, mapping = mapping,  
    data = data, stat = stat,
    position = position, show.legend = show.legend, 
    inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, ...)
  )
}

1 个答案:

答案 0 :(得分:1)

好的,所以问题不在于ggplot,问题出在编写代码的白痴。

在上面的代码中,我写了fill=factor(n),但是n实际上是在条形图上显示的值。相反,我应该使用fill=factor(cyl),它的工作原理完全符合预期。