18

很抱歉没有为我的问题包含任何示例数据。我找不到轻松生成示例形状文件的方法。希望有经验的用户ggplot可以从下面的描述中看到我想做的事情。

我有:

  • data.frame带有样本图信息的X ( plotid, var1, var2, var3, var4, ...)

  • Y带有示例图空间信息的多边形 shapefile

shapefile Y(with maptools) 和fortifying as data.frame Z( ggplot2) 的导入工作正常。melt荷兰国际集团工作同样好X。-ing和to也可以。X_meltedmergeZX_meltedmapdf

这意味着现在我们有了一个data.frame包含空间信息的长格式和var1, var2, var3, ...</p>

现在我想像这样绘制这个数据框:

pl1 <- ggplot(mapdf,aes(long,lat),group=group)
pl1 <- pl1 + geom_polygon(aes(group=group,fill=value),colour="black")
pl1 <- pl1 + facet_grid(variable ~ .)
pl1 <- pl1 + coord_equal(ratio = 1)
pl1

结果是一个漂亮的图,每个变量都有一个面板。面板的地图是相同的,但填充颜色随变量的值而变化。到目前为止,一切都像一个魅力......有一个问题:

变量具有不同的最小值和最大值。例如var10to 5var2from 0to 400var3from 5to10等。在该示例中,填充颜色的图例从0to 400var2画得很好,但var1基本上var3是相同的颜色。

有没有办法可以为刻面的每个面板使用不同的图例?或者这根本不可能(还)用facet_wrapor facet_gridin ggplot

我可以为每个变量制作单独的图并将它们与视口连接起来,但是有很多变量,这将是很多工作。

或者是否有其他包或方法可以用来完成我想做的事情?

非常感谢您的帮助。:)

编辑:在ggplot2-package 描述的帮助下,我构建了一个示例来说明我的问题:

ids <- factor(c("1.1", "2.1", "1.2", "2.2", "1.3", "2.3"))
values <- data.frame(
id = ids,
val1 = cumsum(runif(6, max = 0.5)),
val2 = cumsum(runif(6, max = 50))
)
positions <- data.frame(
id = rep(ids, each = 4),
x = c(2, 1, 1.1, 2.2, 1, 0, 0.3, 1.1, 2.2, 1.1, 1.2, 2.5, 1.1, 0.3,
0.5, 1.2, 2.5, 1.2, 1.3, 2.7, 1.2, 0.5, 0.6, 1.3),
y = c(-0.5, 0, 1, 0.5, 0, 0.5, 1.5, 1, 0.5, 1, 2.1, 1.7, 1, 1.5,
2.2, 2.1, 1.7, 2.1, 3.2, 2.8, 2.1, 2.2, 3.3, 3.2)
)

values <- melt(values)
datapoly <- merge(values, positions, by=c("id"))

p <- ggplot(datapoly, aes(x=x, y=y)) + geom_polygon(aes(fill=value, group=id),colour="black")
p <- p + facet_wrap(~ variable)
p

右侧的面板说明var2了地图上的不同值。然而,在左侧的面板上,所有多边形都具有相同的颜色。这是合乎逻辑的,因为所有面板只使用一种颜色渐变。我可以为每个面板使用不同的颜色渐变吗?

4

5 回答 5

16

目前,每个地块只能有一个比例(对于除 x 和 y 之外的所有内容)。

于 2010-09-28T01:32:49.860 回答
4

与网格善良

align.plots <- function(..., vertical=TRUE){
#http://ggextra.googlecode.com/svn/trunk/R/align.r
  dots <- list(...)
  dots <- lapply(dots, ggplotGrob)
  ytitles <- lapply(dots, function(.g) editGrob(getGrob(.g,"axis.title.y.text",grep=TRUE), vp=NULL))
  ylabels <- lapply(dots, function(.g) editGrob(getGrob(.g,"axis.text.y.text",grep=TRUE), vp=NULL))
  legends <- lapply(dots, function(.g) if(!is.null(.g$children$legends))
                    editGrob(.g$children$legends, vp=NULL) else ggplot2:::.zeroGrob)

  gl <- grid.layout(nrow=length(dots))
  vp <- viewport(layout=gl)
  pushViewport(vp)
  widths.left <- mapply(`+`, e1=lapply(ytitles, grobWidth),
                        e2= lapply(ylabels, grobWidth), SIMPLIFY=F)
  widths.right <- lapply(legends, function(g) grobWidth(g) + if(is.zero(g)) unit(0, "lines") else unit(0.5, "lines")) # safe margin recently added to ggplot2
  widths.left.max <- max(do.call(unit.c, widths.left))
  widths.right.max <- max(do.call(unit.c, widths.right))

  for(ii in seq_along(dots)){
    pushViewport(viewport(layout.pos.row=ii))
    pushViewport(viewport(x=unit(0, "npc") + widths.left.max - widths.left[[ii]],
                          width=unit(1, "npc") - widths.left.max + widths.left[[ii]] -
                                                 widths.right.max + widths.right[[ii]],
                          just="left"))
    grid.draw(dots[[ii]])
  upViewport(2)
  }
}



p <- ggplot(datapoly[datapoly$variable=="val1",], aes(x=x, y=y)) + geom_polygon(aes(fill=value, group=id),colour="black")
p1 <- ggplot(datapoly[datapoly$variable=="val2",], aes(x=x, y=y)) + geom_polygon(aes(fill=value, group=id),colour="black")
align.plots( p,p1)
于 2010-09-28T02:19:45.817 回答
3

10多年后重温这个问题,优秀的ggnewscale包解决了多色标的问题。需要注意的是,您的构面数据需要两个单独的层,因此您必须将其分解一下。将新比例添加到情节中的顺序很重要,因此我建议使用“层 - 比例 - 新比例 - 层 - 比例”的顺序。后续的新比例应该重复'new_scale - layer - scale' 模式。

library(ggplot2)
library(ggnewscale)

ids <- factor(c("1.1", "2.1", "1.2", "2.2", "1.3", "2.3"))
values <- data.frame(
  id = ids,
  val1 = cumsum(runif(6, max = 0.5)),
  val2 = cumsum(runif(6, max = 50))
)
positions <- data.frame(
  id = rep(ids, each = 4),
  x = c(2, 1, 1.1, 2.2, 1, 0, 0.3, 1.1, 2.2, 1.1, 1.2, 2.5, 1.1, 0.3,
        0.5, 1.2, 2.5, 1.2, 1.3, 2.7, 1.2, 0.5, 0.6, 1.3),
  y = c(-0.5, 0, 1, 0.5, 0, 0.5, 1.5, 1, 0.5, 1, 2.1, 1.7, 1, 1.5,
        2.2, 2.1, 1.7, 2.1, 3.2, 2.8, 2.1, 2.2, 3.3, 3.2)
)

values <- reshape2::melt(values)
#> Using id as id variables
datapoly <- merge(values, positions, by=c("id"))

ggplot(datapoly, aes(x=x, y=y)) + 
  geom_polygon(aes(fill=value, group=id),
               data = ~ subset(., variable == "val1"),
               colour="black") +
  scale_fill_distiller(palette = "Reds") +
  new_scale_fill() +
  geom_polygon(aes(fill=value, group=id),
               data = ~ subset(., variable == "val2"),
               colour="black") +
  scale_fill_distiller(palette = "Greens") +
  facet_wrap(~ variable)

reprex 包于 2021-02-12 创建(v1.0.0)

于 2021-02-12T15:39:14.187 回答
2

冒着说明显而易见的风险,您似乎应该按百分比而不是原始值着色。然后您的转换值和您的图例从 0 变为 1。

于 2010-09-27T20:14:35.323 回答
1

也许有点不正统,但你可以尝试考虑你的“价值”。例如:

p <- ggplot(datapoly, aes(x=x, y=y)) + geom_polygon(aes(fill=factor(value), group=id),colour="black")
p <- p + facet_wrap(~ variable)
p

ggplot2 使用因子来创建图例。因此,如果您可以添加一个采用“值”的列并将其分解为因子范围,则可以将“值”替换为范围。

创建一个列,例如“f”:

    id variable        value   x    y f
1  1.1     val1   0.09838607 2.0 -0.5 0.09-0.13
2  1.1     val1   0.09838607 1.0  0.0 0.09-0.13
3  1.1     val1   0.09838607 1.1  1.0 0.09-0.13
4  1.1     val1   0.09838607 2.2  0.5 0.09-0.13
25 2.1     val1   0.13121347 1.0  0.0 0.13-0.20

...

然后使用:

p <- ggplot(datapoly, aes(x=x, y=y)) + geom_polygon(aes(fill=f, group=id),colour="black")
p <- p + facet_wrap(~ variable)
p

您必须指定所需的类别,这可能很耗时。但至少图表会按照你想要的方式显示出来。基本上,您会将数据重新编码到另一列中。这里有些例子:

http://www.statmethods.net/management/variables.html

于 2010-09-27T16:45:04.980 回答