gpt4 book ai didi

R 中的 Riverplot 包 - 网格线或轮廓覆盖的输出图

转载 作者:行者123 更新时间:2023-12-04 01:37:39 25 4
gpt4 key购买 nike

我在 R Riverplot (v0.5) 中制作了一个 Sankey 图,输出在 RStudio 中看起来很小,但是当导出或放大它时,颜色有黑色轮廓或网格线。

The Riverplot image linked here shows the problem

我认为这可能是因为形状的轮廓与我想用于填充的透明度不匹配?

我可能需要找到一种方法来完全消除轮廓(而不是使它们半透明),因为我认为它们也是值为零的流仍然显示为细线的原因。

我的代码在这里:

#loading packages
library(readr)
library("riverplot", lib.loc="C:/Program Files/R/R-3.3.2/library")
library(RColorBrewer)

#loaing data
Cambs_flows <- read_csv("~/RProjects/Cambs_flows4.csv")

#defining the edges
edges = rep(Cambs_flows, col.names = c("N1","N2","Value"))
edges <- data.frame(edges)
edges$ID <- 1:25

#defining the nodes
nodes <- data.frame(ID = c("Cambridge","S Cambs","Rest of E","Rest of UK","Abroad","to Cambridge","to S Cambs","to Rest of E","to Rest of UK","to Abroad"))
nodes$x = c(1,1,1,1,1,2,2,2,2,2)
nodes$y = c(1,2,3,4,5,1,2,3,4,5)

#picking colours
palette = paste0(brewer.pal(5, "Set1"), "90")

#plot styles
styles = lapply(nodes$y, function(n) {
list(col = palette[n], lty = 0, textcol = "black")
})

#matching nodes to names
names(styles) = nodes$ID

#defining the river
r <- makeRiver( nodes, edges,
node_labels = c("Cambridge","S Cambs","Rest of E","Rest of UK","Abroad","to Cambridge","to S Cambs","to Rest of E","to Rest of UK","to Abroad"),
node_styles = styles)

#Plotting
plot( r, plot_area = 0.9)

我的数据在这里
dput(Cambs_flows)
structure(list(N1 = c("Cambridge", "Cambridge", "Cambridge",
"Cambridge", "Cambridge", "S Cambs", "S Cambs", "S Cambs", "S Cambs",
"S Cambs", "Rest of E", "Rest of E", "Rest of E", "Rest of E",
"Rest of E", "Rest of UK", "Rest of UK", "Rest of UK", "Rest of UK",
"Rest of UK", "Abroad", "Abroad", "Abroad", "Abroad", "Abroad"
), N2 = c("to Cambridge", "to S Cambs", "to Rest of E", "to Rest of UK",
"to Abroad", "to Cambridge", "to S Cambs", "to Rest of E", "to Rest of UK",
"to Abroad", "to Cambridge", "to S Cambs", "to Rest of E", "to Rest of UK",
"to Abroad", "to Cambridge", "to S Cambs", "to Rest of E", "to Rest of UK",
"to Abroad", "to Cambridge", "to S Cambs", "to Rest of E", "to Rest of UK",
"to Abroad"), Value = c(0L, 1616L, 2779L, 13500L, 5670L, 2593L,
0L, 2975L, 4742L, 1641L, 2555L, 3433L, 0L, 0L, 0L, 6981L, 3802L,
0L, 0L, 0L, 5670L, 1641L, 0L, 0L, 0L)), class = c("tbl_df", "tbl",
"data.frame"), row.names = c(NA, -25L), .Names = c("N1", "N2",
"Value"), spec = structure(list(cols = structure(list(N1 = structure(list(), class = c("collector_character",
"collector")), N2 = structure(list(), class = c("collector_character",
"collector")), Value = structure(list(), class = c("collector_integer",
"collector"))), .Names = c("N1", "N2", "Value")), default = structure(list(), class = c("collector_guess",
"collector"))), .Names = c("cols", "default"), class = "col_spec"))

最佳答案

罪魁祸首是riverplot::curveseg中的一行.我们可以破解这个函数来修复它,或者还有一个非常简单的解决方法,不需要破解这个函数。事实上,在许多情况下,简单的解决方案可能更可取,但首先我解释了如何破解该功能,以便我们理解为什么该解决方法也有效。如果您只想要简单的解决方案,请滚动到此答案的末尾:

更新:下面建议的更改现已在 Riverplot 版本 0.6 中实现

要编辑该函数,您可以使用

trace(curveseg, edit=T)

然后找到接近函数末尾的那一行
polygon(c(xx[i], xx[i + 1], xx[i + 1], xx[i]), c(yy[i], 
yy[i + 1], yy[i + 1] + w, yy[i] + w), col = grad[i],
border = grad[i])

我们可以在这里看到包作者选择不通过 lty polygon 的参数(更新:见 this answer 解释为什么包作者这样做)。通过添加 lty = 0 更改此行(或者,如果您愿意,可以使用 border = NA )并且它按预期用于 OP 案例。 (但请注意,如果您希望呈现 pdf,这可能无法正常工作 - 请参阅 here )
polygon(c(xx[i], xx[i + 1], xx[i + 1], xx[i]), c(yy[i], 
yy[i + 1], yy[i + 1] + w, yy[i] + w), col = grad[i],
border = grad[i], lty=0)

enter image description here

作为旁注,这也解释了评论中报告的有些奇怪的行为,即“如果您运行两次,第二次情节看起来还可以,尽管将其导出并且线条又回来了”。当 lty未在对 polygon 的调用中指定,它使用的默认值是 lty = par("lty") .最初,默认 par("lty")是一条实线,但在运行一次 riverplot 函数后, par("lty")在调用 riverplot:::draw.nodes 期间设置为 0因此,当 riverplot 时抑制线条是第二次运行。但是,如果您随后尝试导出图像,则打开新设备会重置 par("lty")到它的默认值。

更新函数的另一种方法 此编辑是使用 assignInNamespace用您自己的版本覆盖包函数。像这样:
curveseg.new = function (x0, x1, y0, y1, width = 1, nsteps = 50, col = "#ffcc0066", 
grad = NULL, lty = 1, form = c("sin", "line"))
{
w <- width
if (!is.null(grad)) {
grad <- colorRampPaletteAlpha(grad)(nsteps)
}
else {
grad <- rep(col, nsteps)
}
form <- match.arg(form, c("sin", "line"))
if (form == "sin") {
xx <- seq(-pi/2, pi/2, length.out = nsteps)
yy <- y0 + (y1 - y0) * (sin(xx) + 1)/2
xx <- seq(x0, x1, length.out = nsteps)
}
if (form == "line") {
xx <- seq(x0, x1, length.out = nsteps)
yy <- seq(y0, y1, length.out = nsteps)
}
for (i in 1:(nsteps - 1)) {
polygon(c(xx[i], xx[i + 1], xx[i + 1], xx[i]),
c(yy[i], yy[i + 1], yy[i + 1] + w, yy[i] + w),
col = grad[i], border = grad[i], lty=0)
lines(c(xx[i], xx[i + 1]), c(yy[i], yy[i + 1]), lty = lty)
lines(c(xx[i], xx[i + 1]), c(yy[i] + w, yy[i + 1] + w), lty = lty)
}
}

assignInNamespace('curveseg', curveseg.new, 'riverplot', pos = -1, envir = as.environment(pos))

现在是不需要更改函数的简单解决方案:

只需添加行 par(lty=0)在你绘图之前!!!

关于R 中的 Riverplot 包 - 网格线或轮廓覆盖的输出图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41088751/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com