如何使用ggplot绘制3D散点图?

48

我尝试使用plotly包,但在我的情况下根本不起作用。 ggplot包对于2D图表可以工作,但在添加一个以上的轴时会出现错误。如何解决这个问题?

ggplot(data,aes(x=D1,y=D2,z=D3,color=Sample)) +
  geom_point()

如何添加一个轴并获得3D图?


1
展示你的数据。我一直使用plot3d()来获取像这样的三维图形:https://i.stack.imgur.com/hdMN3.png - Adamm
3
我认为ggplot2不能处理伪3D图形。如果您持不同意见,请详细说明为什么它应该是可能的。同时,请务必提供数据示例。 - IRTFM
3个回答

76

既然您在问题中标记了plotly,并且表示已尝试使用它,我认为给您提供一个在plotly中工作的可行代码解决方案会很有帮助:

创建一些要绘制的数据:

set.seed(417)
library(plotly)
temp <- rnorm(100, mean=30, sd=5)
pressure <- rnorm(100)
dtime <- 1:100

使用Plotly的scatter3d类型绘制您的三维散点图:

plot_ly(x=temp, y=pressure, z=dtime, type="scatter3d", mode="markers", color=temp)

呈现以下内容: 输入图像描述

ggplot 本身不支持3D图形渲染,正如其他人所指出的。


在那里也可以包含一个lm()对象吗? - Ben
3
@Ben,可以的。请查看这个链接这个链接 - onlyphantom
那该怎么做呢? :) - Ben
2
@Ben 为了快速参考,请查看此主题,但如果这不能解决您需要的问题,请在StackOverflow上发布一个问题 - 我很乐意在那里帮助回答。 - onlyphantom

26

一个可能的解决方案是gg3D

gg3D是一个扩展ggplot2以生成3D图形的软件包。它正好做到了您想要的:在ggplot中添加第三个坐标轴。我发现它非常好用,易于使用,并且满足我的有限需求。

以下是从参考文献中摘取的一个示例,用于生成基本图形:

devtools::install_github("AckerDWM/gg3D")

library("gg3D")

## An empty plot with 3 axes
qplot(x=0, y=0, z=0, geom="blank") + 
  theme_void() +
  axes_3D()

空的3D坐标轴

## Axes can be populated with points using the function stat_3D.

data(iris)
ggplot(iris, aes(x=Petal.Width, y=Sepal.Width, z=Petal.Length, color=Species)) + 
  theme_void() +
  axes_3D() +
  stat_3D()

鸢尾花数据

还有其他不涉及 ggplot 的选项。例如出色的 plot3D 包,以及它的扩展 plot3Drgl,可以在 openGL 中作图。


1
截至10月16日,gg3D不可用于r 3.5.1 :( - thermophile
3
需要从GitHub安装软件。devtools::install_github("AckerDWM/gg3D") - Paul Sochacki
1
gg3d或plot3D与gganimate兼容吗? - FredrikH-R

22
在您的问题中,提到了plotly包和ggplot2包。plotly和ggplot2都是很棒的包:plotly擅长创建用户可以交互的动态图,而ggplot2擅长创建静态图以进行极端自定义和科学出版。还可以将ggplot2输出发送到plotly。不幸的是,在撰写本文时(2021年4月),ggplot2不支持原生的3d图。但是,有其他包可用于生成3d图,并且有一些方法可以接近ggplot2的质量。以下是几个选项的评论。这些建议并不是详尽无遗的。 plotly 请参见此线程中onlyphantom的回答。 gg3D 请参见此线程中Marco Stamazza的回答。另请参见下面我的努力。 scatterplot3d 请参见相关线程中Seth的回答。 lattice 请参见相关线程中Backlin的回答。 rgl 请参见维基指南中此概述rayshader 请参见此包的精彩功能概述trans3d

看看data-imaginist如何使用trans3d将一个立方体放入ggplot2。

ggrgl

查看这个酷而有用的coolbutuseless介绍。


现在让我回顾一下我对Lorenz吸引子轨迹的努力。虽然自定义仍然有限,但我在使用gg3D进行PDF输出方面取得了最佳效果。我还包括了一个ggrgl示例。

gg3D

# Packages
library(deSolve)
library(ggplot2)
library(gg3D)  # remotes::install_github("AckerDWM/gg3D")

# Directory
setwd("~/R/workspace/")

# Parameters
parms <- c(a=10, b=8/3, c=28)

# Initial state 
state <- c(x=0.01, y=0.0, z=0.0)

# Time span
times <- seq(0, 50, by=1/200)

# Lorenz system
lorenz <- function(times, state, parms) {
  with(as.list(c(state, parms)), {
    dxdt <- a*(y-x)
    dydt <- x*(c-z)-y
    dzdt <- x*y-b*z
    return(list(c(dxdt, dydt, dzdt)))
  })
}

# Make dataframe
df <- as.data.frame(ode(func=lorenz, y=state, parms=parms, times=times))

# Make plot
make_plot <- function(theta=0, phi=0){
  ggplot(df, aes(x=x, y=y, z=z, colour=time)) +
    axes_3D(theta=theta, phi=phi) +
    stat_3D(theta=theta, phi=phi, geom="path") +
    labs_3D(theta=theta, phi=phi, 
            labs=c("x", "y", "z"), 
            angle=c(0,0,0),
            hjust=c(0,2,2), 
            vjust=c(2,2,-2)) +
    ggtitle("Lorenz butterfly") +
    theme_void() +
    theme(legend.position = "none")
}

make_plot()

make_plot(theta=180,phi=0)

# Save plot as PDF
ggsave(last_plot(), filename="lorenz-gg3d.pdf")

优点:生成高质量的PDF文件:

enter image description here

缺点:仍有限定的自定义选项。但对于我的特定需求来说,目前是最佳选择。
ggrgl
# Packages
library(deSolve)
library(ggplot2)
library(rgl)
  #remotes::install_github("dmurdoch/rgl")
library(ggrgl) 
  # remotes::install_github('coolbutuseless/ggrgl', ref='main')
library(devout)
library(devoutrgl) 
  # remotes::install_github('coolbutuseless/devoutrgl', ref='main')
library(webshot2)
  # remotes::install_github("rstudio/webshot2")
library(ggthemes)

# Directory
setwd("~/R/workspace/")

# Parameters
parms <- c(a=10, b=8/3, c=26.48)

# Initial state 
state <- c(x=0.01, y=0.0, z=0.0)

# Time span
times <- seq(0, 100, by=1/500)

# Lorenz system
lorenz <- function(times, state, parms) {
  with(as.list(c(state, parms)), {
    dxdt <- a*(y-x)
    dydt <- x*(c-z)-y
    dzdt <- x*y-b*z
    return(list(c(dxdt, dydt, dzdt)))
  })
}

# Make dataframe
df <- as.data.frame(ode(func=lorenz, y=state, parms=parms, times=times))

# Make plot
ggplot(df, aes(x=x, y=y, z=z)) +
  geom_path_3d() +
  ggtitle("Lorenz butterfly") -> p

# Render Plot in window
rgldev(fov=30, view_angle=-10, zoom=0.7)
p + theme_ggrgl(16) 

# Save plot as PNG
rgldev(fov=30, view_angle=-10, zoom=0.7,
       file = "~/R/Work/plots/lorenz-attractor/ggrgl/lorenz-ggrgl.png", 
       close_window = TRUE, dpi = 300)
p + theme_ggrgl(16) 
dev.off()

enter image description here

优点:可以像plotly一样旋转图形。可以对基本图进行“主题”设置:

enter image description here

缺点:该图形缺少带标签的第三个轴。无法输出高质量的绘图。虽然我已经能够以PNG格式查看和保存低质量的黑色轨迹,但我无法保存彩色轨迹,除了使用低质量的截屏:

enter image description here

相关主题:在R中绘制3D数据图表, 使用R绘制3D图形


你知道有没有任何能够呈现沿轨迹移动的点的R包吗?谢谢! - Dragos Bandur
如果我理解你的问题正确,我认为你可能会在“gganimate”中找到你要寻找的内容(不确定是否支持3D,但软件包维护者非常乐于助人,可能会有建议):https://gganimate.com/ - PatrickT
1
@ PatrickT:我会看一下。谢谢! - Dragos Bandur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接