我正在尝试使ggplot2接受列表并使列表中的元素可用于其他自定义geom函数。
我有一个新的ggplot函数,可以接受列表:
<?php
class m
{
public $tmp = [];
public function set_foo($foo)
{
$this->tmp['foo'] = $foo;
}
public function set_bar($bar) {
$this->tmp['bar'] = $bar;
}
}
$params = ['foo' => 33, 'bar' => 44];
$m = new m;
foreach($params as $method => $value) {
$method = "set_{$method}";
if (method_exists($m, $method)) {
$m->{$method}($value);
}
}
var_dump($m);
我创建列表,然后绘制第一个data.frame:
ggplot.list <- function(data = NULL,
mapping = ggplot2::aes(),
...,
environment = parent.frame()) {
p <- ggplot2::ggplot(data=data[[1]],mapping=mapping,..., environment=environment)
p$data_ext <- data[[2]]
p
}
理想情况下,我想创建一个类似的东西(不起作用),默认情况下,另一个geom从ggplot对象中获取l <- list(tibble(x=1:10, y=1:10), tibble(x=1:10+100, y =1:10+200))
ggplot(l) + geom_point(aes(x=x,y=y))
data_ext
我看到我的第二个data.frame在ggplot对象中,但是我不知道如何访问它。即geom_point2 <- function (mapping = NULL, data_ext = NULL, stat = "identity", position = "identity",
..., na.rm = FALSE, show.legend = NA, inherit.aes = TRUE)
{
layer(data_ext = data_ext, mapping = mapping, stat = stat, geom = GeomPoint,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...))
}
ggplot(l) + geom_point(aes(x=x,y=y)) + geom_point2(aes(x=x,y=y))
起作用。
我已经尝试过使用ggproto,但我还不了解如何处理ggproto,以及它是否有帮助。
添加 顺便说一句,我可以通过管道实现我想要的东西,但是我不想混淆我的函数的潜在用户:
ggplot(l)$data_ext
答案 0 :(得分:2)
当我开始制作自己的ggproto对象时,重要的指针来自以下链接Extending ggplot2。 TL; DR:如果没有ggproto对象,编写新的几何图形将变得非常困难。
我尝试将矩阵走私到自定义geom_raster()中,这类似于将列表走私到自定义geoms中。我了解到,秤很难训练,即位置秤不知道矩阵的极限是什么,填充秤也不知道矩阵的极限是什么。我到了看起来一切正确的地步,但是颜色栏指南没有显示正确的数字。
现在列表可能会更容易一些,因为您可以更轻松地将它们拆分为有意义的元素,并且可以将列表走私到数据框中。这意味着您可以轻松地执行以下操作并将其提供给ggplot:
mydf <- data.frame(x = 1:3, y = 1:3)
mydf$z <- list(c("A","B"), 1:5, function(x) x/10)
print(mydf)
x y z
1 1 1 A, B
2 2 2 1, 2, 3, 4, 5
3 3 3 function (x) , x/10
我认为,这是将清单走私到Geom的最佳选择。您只是称其为功能的一种额外美感。
g <- ggplot(mydf) + geom_point(aes(x = x, y = y, z = z))
# Warning: Ignoring unknown aesthetics: z
并检查该图层是否具有权限:
layer_data(g)
x y z PANEL group shape colour size fill alpha stroke
1 1 1 A, B 1 -1 19 black 1.5 NA NA 0.5
2 2 2 1, 2, 3, 4, 5 1 -1 19 black 1.5 NA NA 0.5
3 3 3 function (x) , x/10 1 -1 19 black 1.5 NA NA 0.5
而且确实如此,现在您只需要编写自定义的geom面板绘图功能即可在绘图中描绘此列表,我建议您使用上面的链接。
下面唯一要做的就是在绘制点之前打印z
,并接受z
作为可选的美感:
MyGeom <- ggproto(
"MyGeom", GeomPoint,
draw_panel = function(data, panel_params, coord, na.rm = FALSE) {
print(data$z)
GeomPoint$draw_panel(data, panel_params, coord, na.rm = FALSE)
},
optional_aes = "z"
)
现在,您需要一个指向MyGeom
的图层包装器:
geom_mine <- function (mapping = NULL, data = NULL, stat = "identity", position = "identity",
..., na.rm = FALSE, show.legend = NA, inherit.aes = TRUE)
{
layer(mapping = mapping, stat = stat, geom = MyGeom,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...))
}
您现在可以在绘图中使用它:
ggplot(mydf) + geom_mine(aes(x = x, y = y, z = z))
[[1]]
[1] "A" "B"
[[2]]
[1] 1 2 3 4 5
[[3]]
function (x)
x/10
瞧,就像我们说的那样,它会制作剧情并打印z
。
希望这些指针有所帮助!