ggplot2 2.0 新的 stat_ 函数:为给定的美学设置默认比例
ggplot2 2.0 new stat_ function: setting default scale for given aesthetics
我尝试在 R 中使用 ggplot2 的新功能,它允许创建我们自己的 stat_
函数。我正在创建一个简单的方法来计算和绘制二维数组上排列的点之间的插值表面。
我想创建一个需要 x
、y
和 val
美学的 stat_topo(),绘制一个简单的 geom_raster
插值 val
映射到 fill
.
library(ggplot2)
library(dplyr)
library(akima)
cpt_grp <- function(data, scales) {
#interpolate data in 2D
itrp <- akima::interp(data$x,data$y,data$val,linear=F,extrap=T)
out <- expand.grid(x=itrp$x, y=itrp$y,KEEP.OUT.ATTRS = F)%>%
mutate(fill=as.vector(itrp$z))
# str(out)
return(out)
}
StatTopo <- ggproto("StatTopo", Stat,
compute_group = cpt_grp,
required_aes = c("x","y","val")
)
stat_topo <- function(mapping = NULL, data = NULL, geom = "raster",
position = "identity", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE, ...) {
layer(
stat = StatTopo, data = data, mapping = mapping, geom = geom,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}
set.seed(1)
nchan <- 30
d <- data.frame(val = rnorm(nchan), # some random values to be mapped to fill color
x = 1:nchan*cos(1:nchan), # the x and y position of the points to interpolate
y = 1:nchan*sin(1:nchan))
plot(d$x,d$y)
ggplot(d,aes(x=x,y=y,val=val)) +
stat_topo() +
geom_point()
当我运行这个时,我得到以下错误:
Error: numerical color values must be >= 0, found -1
我知道这是因为 fill
审美的尺度不知何故被设置为离散的。
如果我输入:
ggplot(d,aes(x=x,y=y,val=val)) +
stat_topo() +
scale_fill_continuous() +
geom_point()
我得到了我想要的:具有连续色标的预期光栅,我希望 stat_
默认执行 ...
所以我想问题是:
我怎样才能防止 ggplot 在这里设置离散比例,理想情况下在调用我的新 stat_
函数时设置默认比例。
好吧,睡了一觉,有了一个主意,我想这可能会做你想要的。在你的 stat_topo
层函数而不是 ggproto
中,我返回了一个列表,它作为第一个元素,然后通过调用 scale_fill_continuous()
添加到该列表中另一个 ggproto
.
library(ggplot2)
library(dplyr)
library(akima)
cpt_grp <- function(data, scales) {
#interpolate data in 2D
itrp <- akima::interp(data$x,data$y,data$val,linear=F,extrap=T)
out <- expand.grid(x=itrp$x, y=itrp$y,KEEP.OUT.ATTRS = F)%>%
mutate(fill=as.vector(itrp$z))
return(out)
}
StatTopo <- ggproto("StatTopo", Stat,
compute_group = cpt_grp,
required_aes = c("x","y","val")
)
stat_topo <- function(mapping = NULL, data = NULL, geom = "raster",
position = "identity", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE, ...) {
list(
layer(
stat = StatTopo, data = data, mapping = mapping, geom = geom,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm )
),
scale_fill_continuous()
)
}
set.seed(1)
nchan <- 30
d <- data.frame(val = rnorm(nchan), # some random values to be mapped to fill color
x = 1:nchan*cos(1:nchan), # the x and y position of interp points
y = 1:nchan*sin(1:nchan))
ggplot(d,aes(x=x,y=y,val=val)) +
stat_topo() +
geom_point()
生成与上面相同的图片。
显然,在 stat_
函数中创建一个新变量时,需要在 ggproto 定义中使用参数 default_aes = aes(fill = ..fill..)
将其明确关联到将映射到的美学。
这告诉 ggplot 它是一种计算美学,它将根据数据类型选择比例。
所以这里我们需要定义stat_
如下:
cpt_grp <- function(data, scales) {
# interpolate data in 2D
itrp <- akima::interp(data$x,data$y,data$val,linear=F,extrap=T)
out <- expand.grid(x=itrp$x, y=itrp$y,KEEP.OUT.ATTRS = F)%>%
mutate(fill=as.vector(itrp$z))
# str(out)
return(out)
}
StatTopo <- ggproto("StatTopo", Stat,
compute_group = cpt_grp,
required_aes = c("x","y","val"),
default_aes = aes(fill = ..fill..)
)
stat_topo <- function(mapping = NULL, data = NULL, geom = "raster",
position = "identity", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE, ...) {
layer(
stat = StatTopo, data = data, mapping = mapping, geom = geom,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}
然后是下面的代码:
set.seed(1)
nchan <- 30
d <- data.frame(val = rnorm(nchan),
x = 1:nchan*cos(1:nchan),
y = 1:nchan*sin(1:nchan))
ggplot(d,aes(x=x,y=y,val=val)) +
stat_topo() +
geom_point()
按预期生成:
无需手动指定 scale_
,但可以像往常一样轻松调整比例,例如scale_fill_gradient2(low = 'blue',mid='white',high='red')
我在这里得到了这个答案:https://github.com/hadley/ggplot2/issues/1481
我尝试在 R 中使用 ggplot2 的新功能,它允许创建我们自己的 stat_
函数。我正在创建一个简单的方法来计算和绘制二维数组上排列的点之间的插值表面。
我想创建一个需要 x
、y
和 val
美学的 stat_topo(),绘制一个简单的 geom_raster
插值 val
映射到 fill
.
library(ggplot2)
library(dplyr)
library(akima)
cpt_grp <- function(data, scales) {
#interpolate data in 2D
itrp <- akima::interp(data$x,data$y,data$val,linear=F,extrap=T)
out <- expand.grid(x=itrp$x, y=itrp$y,KEEP.OUT.ATTRS = F)%>%
mutate(fill=as.vector(itrp$z))
# str(out)
return(out)
}
StatTopo <- ggproto("StatTopo", Stat,
compute_group = cpt_grp,
required_aes = c("x","y","val")
)
stat_topo <- function(mapping = NULL, data = NULL, geom = "raster",
position = "identity", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE, ...) {
layer(
stat = StatTopo, data = data, mapping = mapping, geom = geom,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}
set.seed(1)
nchan <- 30
d <- data.frame(val = rnorm(nchan), # some random values to be mapped to fill color
x = 1:nchan*cos(1:nchan), # the x and y position of the points to interpolate
y = 1:nchan*sin(1:nchan))
plot(d$x,d$y)
ggplot(d,aes(x=x,y=y,val=val)) +
stat_topo() +
geom_point()
当我运行这个时,我得到以下错误:
Error: numerical color values must be >= 0, found -1
我知道这是因为 fill
审美的尺度不知何故被设置为离散的。
如果我输入:
ggplot(d,aes(x=x,y=y,val=val)) +
stat_topo() +
scale_fill_continuous() +
geom_point()
我得到了我想要的:具有连续色标的预期光栅,我希望 stat_
默认执行 ...
所以我想问题是:
我怎样才能防止 ggplot 在这里设置离散比例,理想情况下在调用我的新 stat_
函数时设置默认比例。
好吧,睡了一觉,有了一个主意,我想这可能会做你想要的。在你的 stat_topo
层函数而不是 ggproto
中,我返回了一个列表,它作为第一个元素,然后通过调用 scale_fill_continuous()
添加到该列表中另一个 ggproto
.
library(ggplot2)
library(dplyr)
library(akima)
cpt_grp <- function(data, scales) {
#interpolate data in 2D
itrp <- akima::interp(data$x,data$y,data$val,linear=F,extrap=T)
out <- expand.grid(x=itrp$x, y=itrp$y,KEEP.OUT.ATTRS = F)%>%
mutate(fill=as.vector(itrp$z))
return(out)
}
StatTopo <- ggproto("StatTopo", Stat,
compute_group = cpt_grp,
required_aes = c("x","y","val")
)
stat_topo <- function(mapping = NULL, data = NULL, geom = "raster",
position = "identity", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE, ...) {
list(
layer(
stat = StatTopo, data = data, mapping = mapping, geom = geom,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm )
),
scale_fill_continuous()
)
}
set.seed(1)
nchan <- 30
d <- data.frame(val = rnorm(nchan), # some random values to be mapped to fill color
x = 1:nchan*cos(1:nchan), # the x and y position of interp points
y = 1:nchan*sin(1:nchan))
ggplot(d,aes(x=x,y=y,val=val)) +
stat_topo() +
geom_point()
生成与上面相同的图片。
显然,在 stat_
函数中创建一个新变量时,需要在 ggproto 定义中使用参数 default_aes = aes(fill = ..fill..)
将其明确关联到将映射到的美学。
这告诉 ggplot 它是一种计算美学,它将根据数据类型选择比例。
所以这里我们需要定义stat_
如下:
cpt_grp <- function(data, scales) {
# interpolate data in 2D
itrp <- akima::interp(data$x,data$y,data$val,linear=F,extrap=T)
out <- expand.grid(x=itrp$x, y=itrp$y,KEEP.OUT.ATTRS = F)%>%
mutate(fill=as.vector(itrp$z))
# str(out)
return(out)
}
StatTopo <- ggproto("StatTopo", Stat,
compute_group = cpt_grp,
required_aes = c("x","y","val"),
default_aes = aes(fill = ..fill..)
)
stat_topo <- function(mapping = NULL, data = NULL, geom = "raster",
position = "identity", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE, ...) {
layer(
stat = StatTopo, data = data, mapping = mapping, geom = geom,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}
然后是下面的代码:
set.seed(1)
nchan <- 30
d <- data.frame(val = rnorm(nchan),
x = 1:nchan*cos(1:nchan),
y = 1:nchan*sin(1:nchan))
ggplot(d,aes(x=x,y=y,val=val)) +
stat_topo() +
geom_point()
按预期生成:
无需手动指定 scale_
,但可以像往常一样轻松调整比例,例如scale_fill_gradient2(low = 'blue',mid='white',high='red')
我在这里得到了这个答案:https://github.com/hadley/ggplot2/issues/1481