如何在 R 中创建曲面图
How to create surface plot in R
我目前正在尝试开发一个曲面图来检查以下数据框的结果。我想在 x 轴上绘制噪声的增加值,在 y 轴上绘制 mu 的增加值,在 z 轴上绘制点估计值。在查看 ggplot2 和 ggplotly 之后,我不清楚如何在表面或 3D 图中绘制这些列中的每一列。
df <- "mu noise0 noise1 noise2 noise3 noise4 noise5
1 1 0.000000 0.9549526 0.8908646 0.919630 1.034607
2 2 1.952901 1.9622004 2.0317115 1.919011 1.645479
3 3 2.997467 0.5292921 2.8592976 3.034377 3.014647
4 4 3.998339 4.0042379 3.9938346 4.013196 3.977212
5 5 5.001337 4.9939060 4.9917115 4.997186 5.009082
6 6 6.001987 5.9929932 5.9882173 6.015318 6.007156
7 7 6.997924 6.9962483 7.0118066 6.182577 7.009172
8 8 8.000022 7.9981131 8.0010066 8.005220 8.024569
9 9 9.004437 9.0066182 8.9667536 8.978415 8.988935
10 10 10.006595 9.9987245 9.9949733 9.993018 10.000646"
提前致谢。
ggplot
接受长格式的数据,这意味着您需要 melt 您的数据集,例如使用 reshape2 中的函数包裹:
dfLong = melt(df,
id.vars = "mu",
variable.name = "noise",
value.name = "meas")
结果列 noise
包含 noise0
、noise1
等条目。您可以提取数字并转换为数字列:
dfLong$noise = with(dfLong, as.numeric(gsub("noise", "", noise)))
这会将您的数据转换为:
mu noise meas
1 1 0 1.0000000
2 2 0 2.0000000
3 3 0 3.0000000
...
根据 ggplot documentation:
ggplot2 can not draw true 3D surfaces, but you can use geom_contour(), geom_contour_filled(), and geom_tile() to visualise 3D surfaces in 2D.
因此,例如:
ggplot(dfLong,
aes(x = noise
y = mu,
fill = meas)) +
geom_tile() +
scale_fill_gradientn(colours = terrain.colors(10))
产生:
这是使用 geom_tile()
的一种方法。首先,您需要将数据框放入更多 Tidy format,目标是包含列:
- mu:这里没有变化
- 噪声: 需要将您的“噪声 0”、“噪声 1”、...列组合在一起,并且
- z: 作为噪声值,我们将使用此列应用
fill=
美学。
为此,我使用了 dplyr
和 gather()
,但还有其他方法(melt()
或 pivot_longer()
也可以)。我还添加了一些代码以仅提取“噪声”列的数字部分,然后将其重新格式化为整数以确保您的 x 轴和 y 轴为 numeric/integers:
# assumes that df is your data as data.frame
df <- df %>% gather(key="noise", value="z", -mu)
df <- df %>% separate(col = "noise", into=c('x', "noise"), sep=5) %>% select(-x)
df$noise <- as.integer(df$noise)
这是您如何绘制它的示例,但美学取决于您。我决定还包括 geom_text()
以显示 df$z
的实际值,以便我们可以更好地了解发生了什么。另外,我使用 rainbow 是因为“它很漂亮”——你可能想从 RColorBrewer
包中选择一个更合适的定量比较量表。
ggplot(df, aes(x=noise, y=mu, fill=z)) + theme_bw() +
geom_tile() +
geom_text(aes(label=round(z, 2))) +
scale_fill_gradientn(colors = rainbow(5))
编辑: 要回答 OP 的跟进,是的,您也可以通过 plotly
展示这一点。这是一个直接的过渡:
p <- plot_ly(
df, x= ~noise, y= ~mu, z= ~z,
type='mesh3d', intensity = ~z,
colors= colorRamp(rainbow(5))
)
p
此处为静态图片:
显示这组特定信息的更丰富的方法是通过创建 df$delta_z
来查看 df$z
与 df$mu
相关的变化,然后使用它来绘制. (您也可以像上面那样通过 ggplot() + geom_tile()
绘图):
df$delta_z <- df$z - df$mu
p1 <- plot_ly(
df, x= ~noise, y= ~mu, z= ~delta_z,
type='mesh3d', intensity = ~delta_z,
colors= colorRamp(rainbow(5))
)
给你这个(这里是静态图片):
我目前正在尝试开发一个曲面图来检查以下数据框的结果。我想在 x 轴上绘制噪声的增加值,在 y 轴上绘制 mu 的增加值,在 z 轴上绘制点估计值。在查看 ggplot2 和 ggplotly 之后,我不清楚如何在表面或 3D 图中绘制这些列中的每一列。
df <- "mu noise0 noise1 noise2 noise3 noise4 noise5
1 1 0.000000 0.9549526 0.8908646 0.919630 1.034607
2 2 1.952901 1.9622004 2.0317115 1.919011 1.645479
3 3 2.997467 0.5292921 2.8592976 3.034377 3.014647
4 4 3.998339 4.0042379 3.9938346 4.013196 3.977212
5 5 5.001337 4.9939060 4.9917115 4.997186 5.009082
6 6 6.001987 5.9929932 5.9882173 6.015318 6.007156
7 7 6.997924 6.9962483 7.0118066 6.182577 7.009172
8 8 8.000022 7.9981131 8.0010066 8.005220 8.024569
9 9 9.004437 9.0066182 8.9667536 8.978415 8.988935
10 10 10.006595 9.9987245 9.9949733 9.993018 10.000646"
提前致谢。
ggplot
接受长格式的数据,这意味着您需要 melt 您的数据集,例如使用 reshape2 中的函数包裹:
dfLong = melt(df,
id.vars = "mu",
variable.name = "noise",
value.name = "meas")
结果列 noise
包含 noise0
、noise1
等条目。您可以提取数字并转换为数字列:
dfLong$noise = with(dfLong, as.numeric(gsub("noise", "", noise)))
这会将您的数据转换为:
mu noise meas
1 1 0 1.0000000
2 2 0 2.0000000
3 3 0 3.0000000
...
根据 ggplot documentation:
ggplot2 can not draw true 3D surfaces, but you can use geom_contour(), geom_contour_filled(), and geom_tile() to visualise 3D surfaces in 2D.
因此,例如:
ggplot(dfLong,
aes(x = noise
y = mu,
fill = meas)) +
geom_tile() +
scale_fill_gradientn(colours = terrain.colors(10))
产生:
这是使用 geom_tile()
的一种方法。首先,您需要将数据框放入更多 Tidy format,目标是包含列:
- mu:这里没有变化
- 噪声: 需要将您的“噪声 0”、“噪声 1”、...列组合在一起,并且
- z: 作为噪声值,我们将使用此列应用
fill=
美学。
为此,我使用了 dplyr
和 gather()
,但还有其他方法(melt()
或 pivot_longer()
也可以)。我还添加了一些代码以仅提取“噪声”列的数字部分,然后将其重新格式化为整数以确保您的 x 轴和 y 轴为 numeric/integers:
# assumes that df is your data as data.frame
df <- df %>% gather(key="noise", value="z", -mu)
df <- df %>% separate(col = "noise", into=c('x', "noise"), sep=5) %>% select(-x)
df$noise <- as.integer(df$noise)
这是您如何绘制它的示例,但美学取决于您。我决定还包括 geom_text()
以显示 df$z
的实际值,以便我们可以更好地了解发生了什么。另外,我使用 rainbow 是因为“它很漂亮”——你可能想从 RColorBrewer
包中选择一个更合适的定量比较量表。
ggplot(df, aes(x=noise, y=mu, fill=z)) + theme_bw() +
geom_tile() +
geom_text(aes(label=round(z, 2))) +
scale_fill_gradientn(colors = rainbow(5))
编辑: 要回答 OP 的跟进,是的,您也可以通过 plotly
展示这一点。这是一个直接的过渡:
p <- plot_ly(
df, x= ~noise, y= ~mu, z= ~z,
type='mesh3d', intensity = ~z,
colors= colorRamp(rainbow(5))
)
p
此处为静态图片:
显示这组特定信息的更丰富的方法是通过创建 df$delta_z
来查看 df$z
与 df$mu
相关的变化,然后使用它来绘制. (您也可以像上面那样通过 ggplot() + geom_tile()
绘图):
df$delta_z <- df$z - df$mu
p1 <- plot_ly(
df, x= ~noise, y= ~mu, z= ~delta_z,
type='mesh3d', intensity = ~delta_z,
colors= colorRamp(rainbow(5))
)
给你这个(这里是静态图片):