- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有什么方法可以在 geom_curve 线的中心或附近添加标签吗?目前,我只能通过标记曲线的起点或终点来做到这一点。
library(tidyverse)
library(ggrepel)
df <- data.frame(x1 = 1, y1 = 1, x2 = 2, y2 = 3, details = "Object Name")
ggplot(df, aes(x = x1, y = y1, label = details)) +
geom_point(size = 4) +
geom_point(aes(x = x2, y = y2),
pch = 17, size = 4) +
geom_curve(aes(x = x1, y = y1, xend = x2, yend = y2)) +
geom_label(nudge_y = 0.05) +
geom_label_repel(box.padding = 2)
我希望有某种方法可以自动标记坐标 x=1.75、y=1.5 附近的曲线。有没有我还没见过的解决方案?我想要的图表非常繁忙,标记原点使得更难看到正在发生的事情,而标记弧线会产生更清晰的输出。
最佳答案
我已经找到了解决这个问题的方法。它又大又笨重,但很有效。
核心问题是geom_curve()
不绘制设定的路径,而是随着绘图窗口的纵横比移动和缩放。如果不使用 coord_fixed(ratio=1) 锁定纵横比,我就无法轻松预测 geom_curve() 线段的中点在哪里。
因此,我开始寻找曲线的中点,然后强制曲线穿过该点,稍后我将对其进行标记。为了找到中点,我必须从 grid package 复制两个函数:
library(grid)
library(tidyverse)
library(ggrepel)
# Find origin of rotation
# Rotate around that origin
calcControlPoints <- function(x1, y1, x2, y2, curvature, angle, ncp,
debug=FALSE) {
# Negative curvature means curve to the left
# Positive curvature means curve to the right
# Special case curvature = 0 (straight line) has been handled
xm <- (x1 + x2)/2
ym <- (y1 + y2)/2
dx <- x2 - x1
dy <- y2 - y1
slope <- dy/dx
# Calculate "corner" of region to produce control points in
# (depends on 'angle', which MUST lie between 0 and 180)
# Find by rotating start point by angle around mid point
if (is.null(angle)) {
# Calculate angle automatically
angle <- ifelse(slope < 0,
2*atan(abs(slope)),
2*atan(1/slope))
} else {
angle <- angle/180*pi
}
sina <- sin(angle)
cosa <- cos(angle)
# FIXME: special case of vertical or horizontal line ?
cornerx <- xm + (x1 - xm)*cosa - (y1 - ym)*sina
cornery <- ym + (y1 - ym)*cosa + (x1 - xm)*sina
# Debugging
if (debug) {
grid.points(cornerx, cornery, default.units="inches",
pch=16, size=unit(3, "mm"),
gp=gpar(col="grey"))
}
# Calculate angle to rotate region by to align it with x/y axes
beta <- -atan((cornery - y1)/(cornerx - x1))
sinb <- sin(beta)
cosb <- cos(beta)
# Rotate end point about start point to align region with x/y axes
newx2 <- x1 + dx*cosb - dy*sinb
newy2 <- y1 + dy*cosb + dx*sinb
# Calculate x-scale factor to make region "square"
# FIXME: special case of vertical or horizontal line ?
scalex <- (newy2 - y1)/(newx2 - x1)
# Scale end points to make region "square"
newx1 <- x1*scalex
newx2 <- newx2*scalex
# Calculate the origin in the "square" region
# (for rotating start point to produce control points)
# (depends on 'curvature')
# 'origin' calculated from 'curvature'
ratio <- 2*(sin(atan(curvature))^2)
origin <- curvature - curvature/ratio
# 'hand' also calculated from 'curvature'
if (curvature > 0)
hand <- "right"
else
hand <- "left"
oxy <- calcOrigin(newx1, y1, newx2, newy2, origin, hand)
ox <- oxy$x
oy <- oxy$y
# Calculate control points
# Direction of rotation depends on 'hand'
dir <- switch(hand,
left=-1,
right=1)
# Angle of rotation depends on location of origin
maxtheta <- pi + sign(origin*dir)*2*atan(abs(origin))
theta <- seq(0, dir*maxtheta,
dir*maxtheta/(ncp + 1))[c(-1, -(ncp + 2))]
costheta <- cos(theta)
sintheta <- sin(theta)
# May have BOTH multiple end points AND multiple
# control points to generate (per set of end points)
# Generate consecutive sets of control points by performing
# matrix multiplication
cpx <- ox + ((newx1 - ox) %*% t(costheta)) -
((y1 - oy) %*% t(sintheta))
cpy <- oy + ((y1 - oy) %*% t(costheta)) +
((newx1 - ox) %*% t(sintheta))
# Reverse transformations (scaling and rotation) to
# produce control points in the original space
cpx <- cpx/scalex
sinnb <- sin(-beta)
cosnb <- cos(-beta)
finalcpx <- x1 + (cpx - x1)*cosnb - (cpy - y1)*sinnb
finalcpy <- y1 + (cpy - y1)*cosnb + (cpx - x1)*sinnb
# Debugging
if (debug) {
ox <- ox/scalex
fox <- x1 + (ox - x1)*cosnb - (oy - y1)*sinnb
foy <- y1 + (oy - y1)*cosnb + (ox - x1)*sinnb
grid.points(fox, foy, default.units="inches",
pch=16, size=unit(1, "mm"),
gp=gpar(col="grey"))
grid.circle(fox, foy, sqrt((ox - x1)^2 + (oy - y1)^2),
default.units="inches",
gp=gpar(col="grey"))
}
list(x=as.numeric(t(finalcpx)), y=as.numeric(t(finalcpy)))
}
calcOrigin <- function(x1, y1, x2, y2, origin, hand) {
# Positive origin means origin to the "right"
# Negative origin means origin to the "left"
xm <- (x1 + x2)/2
ym <- (y1 + y2)/2
dx <- x2 - x1
dy <- y2 - y1
slope <- dy/dx
oslope <- -1/slope
# The origin is a point somewhere along the line between
# the end points, rotated by 90 (or -90) degrees
# Two special cases:
# If slope is non-finite then the end points lie on a vertical line, so
# the origin lies along a horizontal line (oslope = 0)
# If oslope is non-finite then the end points lie on a horizontal line,
# so the origin lies along a vertical line (oslope = Inf)
tmpox <- ifelse(!is.finite(slope),
xm,
ifelse(!is.finite(oslope),
xm + origin*(x2 - x1)/2,
xm + origin*(x2 - x1)/2))
tmpoy <- ifelse(!is.finite(slope),
ym + origin*(y2 - y1)/2,
ifelse(!is.finite(oslope),
ym,
ym + origin*(y2 - y1)/2))
# ALWAYS rotate by -90 about midpoint between end points
# Actually no need for "hand" because "origin" also
# encodes direction
# sintheta <- switch(hand, left=-1, right=1)
sintheta <- -1
ox <- xm - (tmpoy - ym)*sintheta
oy <- ym + (tmpox - xm)*sintheta
list(x=ox, y=oy)
}
有了这个,我计算了每条记录的中点
df <- data.frame(x1 = 1, y1 = 1, x2 = 10, y2 = 10, details = "Object Name")
df_mid <- df %>%
mutate(midx = calcControlPoints(x1, y1, x2, y2,
angle = 130,
curvature = 0.5,
ncp = 1)$x) %>%
mutate(midy = calcControlPoints(x1, y1, x2, y2,
angle = 130,
curvature = 0.5,
ncp = 1)$y)
然后我制作图表,但绘制两条单独的曲线。一个从原点到计算的中点,另一个从中点到目的地。寻找中点和绘制这些曲线的角度和曲率设置很棘手,以防止结果明显看起来像两条不同的曲线。
ggplot(df_mid, aes(x = x1, y = y1)) +
geom_point(size = 4) +
geom_point(aes(x = x2, y = y2),
pch = 17, size = 4) +
geom_curve(aes(x = x1, y = y1, xend = midx, yend = midy),
curvature = 0.25, angle = 135) +
geom_curve(aes(x = midx, y = midy, xend = x2, yend = y2),
curvature = 0.25, angle = 45) +
geom_label_repel(aes(x = midx, y = midy, label = details),
box.padding = 4,
nudge_x = 0.5,
nudge_y = -2)
虽然答案并不理想或不优雅,但它可以随着大量记录而扩展。
关于r - 将标签添加到 geom_curve 线的中心 (ggplot),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49327247/
我创建了一个用户可以添加测试的字段。这一切运行顺利我只希望当用户点击(添加另一个测试)然后上一个(添加另一个测试)删除并且这个显示在新字段中。 所有运行良好的唯一问题是点击(添加另一个字段)之前添加另
String[] option = {"Adlawan", "Angeles", "Arreza", "Benenoso", "Bermas", "Brebant
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我正在努力将 jQuery 滚动功能添加到 nav-tab (Bootstrap 3)。我希望用户能够选择他们想要的选项卡,并在选项卡内容中有一个可以平滑滚动到 anchor 的链接。这是我的代码,可
我正在尝试在用户登录后再添加 2 个 ui 选项卡。首先,我尝试做一个之后。 $('#slideshow').tabs('remove', '4'); $("#slideshow ul li:last
我有一个包含选择元素的表单,我想通过选择添加和删除其中一些元素。这是html代码(这里也有jsfiddle http://jsfiddle.net/txhajy2w/):
正在写这个: view.backgroundColor = UIColor.white.withAlphaComponent(0.9) 等同于: view.backgroundColor = UICo
好的,如果其中有任何信息,我想将这些列添加到一起。所以说我有 账户 1 2 3 . 有 4 个帐户空间,但只有 3 个帐户。我如何创建 java 脚本来添加它。 最佳答案 Live Example H
我想知道是否有一种有效的预制算法来确定一组数字的和/差是否可以等于不同的数字。示例: 5、8、10、2,使用 + 或 - 等于 9。5 - 8 = -3 + 10 = 7 + 2 = 9 如果有一个预
我似乎有一个卡住的 git repo。它卡在所有基本的添加、提交命令上,git push 返回所有内容为最新的。 从其他帖子我已经完成了 git gc 和 git fsck/ 我认为基本的调试步骤是
我的 Oracle SQL 查询如下- Q1- select hca.account_number, hca.attribute3, SUM(rcl.extended_amou
我正在阅读 http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingG
我正在尝试添加一个“加载更多”按钮并限制下面的结果,这样投资组合页面中就不会同时加载 1000 个内容,如下所示:http://typesetdesign.com/portfolio/ 我对 PHP
我遇到这个问题,我添加了 8 个文本框,它工作正常,但是当我添加更多文本框(如 16 个文本框)时,它不会添加最后一个文本框。有人遇到过这个问题吗?提前致谢。 Live Link: JAVASCRIP
add/remove clone first row default not delete 添加/删除克隆第一行默认不删除&并获取正确的SrNo(例如:添加3行并在看到问题后删除SrNo.2)
我编码this ,但删除按钮不起作用。我在控制台中没有任何错误.. var counter = 0; var dataList = document.getElementById('materi
我有一个类似数组的对象: [1:数组[10]、2:数组[2]、3:数组[2]、4:数组[2]、5:数组[3]、6:数组[1]] 我正在尝试删除前两个元素,执行一些操作,然后将它们再次插入到同一位置。
使用的 Delphi 版本:2007 你好, 我有一个 Tecord 数组 TInfo = Record Name : String; Price : Integer; end; var Info
我使用了基本的 gridster 代码,然后我声明了通过按钮添加和删除小部件的函数它工作正常但是当我将调整大小功能添加到上面的代码中时,它都不起作用(我的意思是调整大小,添加和删除小部件) 我的js代
title 323 323 323 title 323 323 323 title 323 323 323 JS $(document).keydown(function(e){
我是一名优秀的程序员,十分优秀!