我想使用ggplot创建一个类似于下面的色盲测试。
基本思想是使用java.nio.file.NoSuchFileException: **the directory**
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsDirectoryStream.<init>(WindowsDirectoryStream.java:86)
at sun.nio.fs.WindowsFileSystemProvider.newDirectoryStream(WindowsFileSystemProvider.java:518)
at java.nio.file.Files.newDirectoryStream(Files.java:457)
at java.nio.file.Files.list(Files.java:3451)
(或者可能是voronoi图,或者甚至可能是上图中的圆圈)作为起点,并定义一个数据帧,当在ggplot中绘制时,会产生图像。
我们首先要创建一个数据集,例如:
geom_hex
然后绘制这个:
df <- data.frame(x = rnorm(10000), y = rnorm(10000))
给出了下图:
主要的缺失步骤是创建一个实际绘制有意义符号(字母或数字)的数据集,并且我不确定如何最好地进行此操作而不需要精心绘制坐标。理想情况下,人们可以从图像文件中读取坐标。
最后,稍微整理可以通过移除边远点来围绕绘图边缘。
非常欢迎所有建议!
更接近我所追求的目标,我们可以使用下面字母'e'的图像:
使用ggplot(df, aes(x, y)) +
geom_hex() +
coord_equal() +
scale_fill_gradient(low = "red", high = "green", guide = FALSE) +
theme_void()
包,我们可以阅读此内容并将其转换为数据帧:
imager
然后使用img <- imager::load.image("e.png")
df <- as.data.frame(img)
绘制该数据框:
geom_raster
如果我们使用ggplot(df, aes(x, y)) +
geom_raster(aes(fill = value)) +
coord_equal() +
scale_y_continuous(trans = scales::reverse_trans()) +
scale_fill_gradient(low = "red", high = "green", guide = FALSE) +
theme_void()
代替geom_hex
,我们可以得到以下情节:
geom_raster
所以,到达那里但显然还有很长的路要走......
答案 0 :(得分:5)
这是创建此图的方法:
您需要的套餐:
library(tidyverse)
library(packcircles)
将图像输入值的二维矩阵(x和y坐标)。为此,我将e的.png文件下载为“e.png”并保存在我的工作目录中。然后进行一些处理:
img <- png::readPNG("e.png")
# From http://stackoverflow.com/questions/16496210/rotate-a-matrix-in-r
rotate <- function(x) t(apply(x, 2, rev))
# Convert to one colour layer and rotate it to be in right direction
img <- rotate(img[,,1])
# Check that matrix makes sense:
image(img)
接下来,创建一大堆圈子!我是根据this post做到的。
# Create random "circles"
# *** THESE VALUES WAY NEED ADJUSTING
ncircles <- 1200
offset <- 100
rmax <- 80
x_limits <- c(-offset, ncol(img) + offset)
y_limits <- c(-offset, nrow(img) + offset)
xyr <- data.frame(
x = runif(ncircles, min(x_limits), max(x_limits)),
y = runif(ncircles, min(y_limits), max(y_limits)),
r = rbeta(ncircles, 1, 10) * rmax)
# Find non-overlapping arrangement
res <- circleLayout(xyr, x_limits, y_limits, maxiter = 1000)
cat(res$niter, "iterations performed")
#> 1000 iterations performed
# Convert to data for plotting (just circles for now)
plot_d <- circlePlotData(res$layout)
# Check circle arrangement
ggplot(plot_d) +
geom_polygon(aes(x, y, group=id), colour = "white", fill = "skyblue") +
coord_fixed() +
theme_minimal()
最后,插入每个圆的中心的图像像素值。这将指示圆是否在形状上居中。添加一些噪音以获得颜色和绘图的差异。
# Get x,y positions of centre of each circle
circle_positions <- plot_d %>%
group_by(id) %>%
summarise(x = min(x) + (diff(range(x)) / 2),
y = min(y) + (diff(range(y)) / 2))
# Interpolate on original image to get z value for each circle
circle_positions <- circle_positions %>%
mutate(
z = fields::interp.surface(
list(x = seq(nrow(img)), y = seq(ncol(img)), z = img),
as.matrix(.[, c("x", "y")])),
z = ifelse(is.na(z), 1, round(z)) # 1 is the "empty" area shown earlier
)
# Add a little noise to the z values
set.seed(070516)
circle_positions <- circle_positions %>%
mutate(z = z + rnorm(n(), sd = .1))
# Bind z value to data for plotting and use as fill
plot_d %>%
left_join(select(circle_positions, id, z)) %>%
ggplot(aes(x, y, group = id, fill = z)) +
geom_polygon(colour = "white", show.legend = FALSE) +
scale_fill_gradient(low = "#008000", high = "#ff4040") +
coord_fixed() +
theme_void()
#> Joining, by = "id"
要获得正确的颜色,请在scale_fill_gradient