- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为 ggplot
创建一个新几何图形如所述here ,同时对其进行调整以处理简单特征对象。
作为一个例子,让我们进行绘制一组点的凸包的相同练习。因此,我写了一个新的 geom_envelope()
函数借用 geom_sf()
的元素和相应的 GeomEnvelope
ggproto
执行覆盖 draw_group()
的计算的对象方法(因为我想要一个多边形来代表全套点)。
但是,我必须遗漏一些东西,因为我无法绘制多边形。我已经尝试了一段时间,但我要么得到错误,要么没有绘制任何内容。
library(sf); library(ggplot2); library(dplyr)
Npts <- 10
pts <- matrix(runif(2*Npts), ncol = 2) %>%
st_multipoint() %>%
st_sfc() %>%
st_cast("POINT") %>%
st_sf()
GeomEnvelope <- ggproto(
"GeomEnvelope", GeomSf,
required_aes = "geometry",
default_aes = aes(
shape = NULL,
colour = "grey20",
fill = "white",
size = NULL,
linetype = 1,
alpha = 0.5,
stroke = 0.5
),
draw_key = draw_key_polygon,
draw_group = function(data, panel_params, coord) {
n <- nrow(data)
if (n <= 2) return(grid::nullGrob())
gp <- gpar(
colour = data$colour,
size = data$size,
linetype = data$linetype,
fill = alpha(data$fill, data$alpha),
group = data$group,
stringsAsFactors = FALSE
)
geometry <- sf::st_convex_hull(st_combine(sf::st_as_sf(data)))
sf::st_as_grob(geometry, pch = data$shape, gp = gp)
}
)
geom_envelope <- function(
mapping = aes(),
data = NULL,
position = "identity",
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE,
...) {
if (!is.null(data) && ggplot2:::is_sf(data)) {
geometry_col <- attr(data, "sf_column")
}
else {
geometry_col <- "geometry"
}
if (is.null(mapping$geometry)) {
mapping$geometry <- as.name(geometry_col)
}
c(
layer(
geom = GeomEnvelope,
data = data,
mapping = mapping,
stat = "identity",
position = position,
show.legend = if (is.character(show.legend))
TRUE
else
show.legend,
inherit.aes = inherit.aes,
params = list(
na.rm = na.rm,
legend = if (is.character(show.legend))
show.legend
else
"polygon",
...
)
),
coord_sf(default = TRUE)
)
}
ggplot(pts) + geom_sf() + geom_envelope() + theme_bw()
最佳答案
如果这是您的实际用例(而不是它的简化示例),那么我想说您正在寻找的基本部分是自定义 统计 , 不是自定义 几何 .数据计算/操作应该发生在前者中。
(作为引用,我通常查看 GeomBoxplot
/ StatBoxplot
中的代码以找出应该发生的事情,因为该用例包括一堆分位数/异常值的计算,以及不同 grob 元素的组合接受各种美学映射。)
具有可重复性的随机种子数据:
set.seed(123)
pts <- matrix(runif(2*Npts), ncol = 2) %>%
st_multipoint() %>%
st_sfc() %>%
st_cast("POINT") %>%
st_sf()
StatEnvelope
会将数据集传递给相关的几何层,并将每组内的几何值集合(如果未指定分组美学,则整个数据集将被视为一组)转换为凸包:
StatEnvelope <- ggproto(
"StatEnvelope", Stat,
required_aes = "geometry",
compute_group = function(data, scales) {
if(nrow(data) <= 2) return (NULL)
data %>%
group_by_at(vars(-geometry)) %>%
summarise(geometry = sf::st_convex_hull(sf::st_combine(geometry))) %>%
ungroup()
}
)
ggplot(pts) +
geom_sf() +
geom_sf(stat = StatEnvelope,
alpha = 0.5, color = "grey20", fill = "white", size = 0.5) +
theme_bw()
geom_sf
,在创建信封方面做得非常好。如果我们想指定一些默认的美学参数,而不是在
geom_sf
的每个实例中重复,我们仍然不需要定义一个新的 Geom。修改现有
geom_sf
的函数会做得很好。
geom_envelope <- function(...){
suppressWarnings(geom_sf(stat = StatEnvelope,
..., # any aesthetic argument specified in the function
# will take precedence over the default arguments
# below, with suppressWarning to mute warnings on
# any duplicated aesthetics
alpha = 0.5, color = "grey20", fill = "white", size = 0.5))
}
# outputs same plot as before
ggplot(pts) +
geom_sf() +
geom_envelope() +
theme_bw()
# with different aesthetic specifications for demonstration
ggplot(pts) +
geom_sf() +
geom_envelope(alpha = 0.1, colour = "brown", fill = "yellow", size = 3) +
theme_bw()
"setting up parameters"
, 或
"drawing panel, step 3"
等。这使我能够很好地了解引擎盖下发生的事情,并在函数(不可避免地)在第 1 次/第 2 次/.../第 n 次尝试时返回错误时跟踪出错的地方。
print("draw group")
GeomEnvelope
的开头的
draw_group
运行前的函数
ggplot(pts) + geom_sf() + geom_envelope() + theme_bw()
,我们将观察到控制台中没有任何打印的消息。换句话说,
draw_group
函数从未被调用 ,因此其中定义的任何数据操作对输出都没有影响。
draw_*
Geom*
中的函数,当我们想要进行修改时,这可能会令人困惑。来自
code for Geom
,我们可以看到层次结构如下:
draw_layer
(包括 do.call(self$draw_panel, args)
行)draw_panel
(包括 self$draw_group(group, panel_params, coord, ...)
行)draw_group
( Geom
未实现)。 draw_layer
触发器
draw_panel
, 和
draw_panel
触发器
draw_group
. (镜像此,在
Stat
,
compute_layer
触发
compute_panel
和
compute_panel
触发
compute_group
。)
GeomSf
,继承自
Geom
(代码
here ),覆盖
Geom
的
draw_panel
带有返回
sf_grob(...)
的代码块的函数, 和
不 触发
draw_group
.
GeomEnvelope
继承
GeomSf
的
draw_panel
函数,它的
draw_group
中没有任何内容功能很重要。图中绘制的内容取决于
draw_panel
,以及
geom_envelope
问题中的层执行与
geom_sf
基本相同的任务,分别绘制每个单独的点。如果您删除/注释掉
geom_sf
层,你会看到相同的点;仅使用 color = "grey20"、alpha = 0.5 等,如
GeomSf
中所述的
default_aes
.
fill = "white"
未使用,因为
geom_sf
默认为
GeomPoint
的点数据默认美学,这意味着它继承了
GeomPoint
的
pch = 19
的点形状,并绘制了一个实体圆不受任何填充值的影响。)
关于r - 使用 sf 对象的自定义几何图形扩展 ggplot2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55811839/
我是 C++ 的新手,所以请放轻松。 我正在尝试使用 sfml 创建 RenderWindow。然后,在创建播放器时,该播放器关联的“窗口”对象被设置为先前创建的 RenderWindow。我的目的是
我有一个 sf 的列表我想行绑定(bind)以创建单个 sf 的对象目的。我正在寻找类似于 data.table::rbindlist 的函数,这将以有效的方式堆叠各个对象。 可重现示例的数据: my
我正在尝试在 R 中使用 sf 创建一个 95% 的最小凸多边形。只要我只将数据分组到 1 个变量上,我的代码就可以正常工作,但是当我分组到两个变量上时,输出将失去其 sf 类并且改为 grouped
我试图使用内连接或左连接连接两个 sf 数据帧。这些数据框内部都有几何列。我不断收到错误: check_join(x, y) 中的错误: y 应该是一个 data.frame;对于空间连接,使用 st
我对使用 SFML 图形库中的 sf::Shape 有疑问。在我的游戏中,我使用 sf::RectangleShapes。例如用户界面或播放器。这是一个和平的代码: std::unique_ptr r
我正在学习 C++ 中的 SFML 库。我一直在尝试通过制作一个包含两个独立的 std::map 的音乐类 (sf::Music) 和声音 (sf::Sound) 来实现一种在我的游戏中组织音频的有效
有没有一种简单的方法可以使 sf::Text 对象在 sf::RectangleShape 对象中居中? 文本具有可变长度,但在创建后不会改变。 我正在使用 SFML 2.4。 最佳答案 将一个对象置
在我的 SwiftUI 应用程序中,我的字符串名称是 SF 符号图像的名称,或存储在 Assets 目录中的图像。 我想创建一个 View ,首先尝试将图像显示为 SF 符号图像,如果不存在具有该名称
我一直在使用EhCache在我的项目中实现一些缓存。我已经将以下依赖项添加到我的pom.xml中 org.springframework spring-context 4.
我想创建一个数组,其中包含将绘制到窗口上的所有 Sprite 、文本和形状,我的问题是如何使这个数组同时具有 sf::Drawable 和 sf::Transformable? 最佳答案 您需要创建一
我得到了一个派生自 sf::Packet 的类,它在其构造函数中传递了一个引用 iots 类型的 Integer。现在在构造函数中,我尝试将 Integer 添加到 sf::Packet 的数据中,如
当我尝试编译以下代码时: SFMLSet.cpp: #include "SFMLSet.h" SFMLSet::SFMLSet(string texturePath) { if(!textur
我正在使用 sf::Clock 来控制循环。 我想知道是否允许我使用超过 1 个 sf::Clock,如果允许,是否所有“时钟”都将正常运行并按预期工作在所有操作系统上。 例如: sf::Clock
我将C++图形中的SFML libraby用于我的国际象棋游戏。 当您在游戏中移动棋子时,会发生鼠标左键事件。所以这是我最初的跟踪方式。 sf::Event e; if (e.type == sf::
我正在尝试使用 SFML 库制作简单的按钮。当我将鼠标放在按钮上时,该按钮应该会更改其文本颜色。 void Button::updateColor(sf::Vector2i MousePos) {
void update(bool moright, bool moleft) { Clock Clock(); if (moright == true){
我的 JSON 有问题。我的代码中的这一行抛出异常 String jsontxt = IOUtils.toString(new FileInputStream(Filename), "UTF-8");
代码如下: 引擎.h #include #include #include #include #include #include #include class Engine { publ
我意识到这可能是重复的,但我搜索了许多论坛和问题,知道是什么原因导致了问题,但无法在此处找到它。我正在使用 SFML 2.0,我已将错误追踪到: void GameObjectManager::Dra
我在 sf 类型的简单特征( POINT )中保存了多个轨迹.我想计算后续位置(即行)之间的欧几里得距离。到目前为止,我已经使用 Pythagorean formula for calculating
我是一名优秀的程序员,十分优秀!