如何在Matplotlib或Mayavi中表示以下3D数据?

7
我有一组大量的数据,希望在3D中呈现出来以便发现模式。我已经花了很多时间阅读、研究和编码,但后来我意识到我的主要问题并不是编程,而是选择一种可视化数据的方法。
Matplotlib的mplot3d提供了许多选项(线框图、轮廓图、填充轮廓等),MayaVi也是如此。但是有这么多选择(每个选择都有自己的学习曲线),我几乎迷失了方向,不知道从哪里开始!所以我的问题本质上是,如果你必须处理这些数据,你会使用哪种绘图方法?
我的数据是基于日期的。对于每个时间点,我绘制一个值(列表“Actual”)。
但是对于每个时间点,我还有一个上限、一个下限和一个中间点。这些限制和中点是基于一个种子,在不同的平面上。
我想在“实际”阅读出现重大变化时或之前发现该点或识别模式。当所有平面上的上限相遇或接近时,是不是发生了这种情况?当实际值触及上/中/下限时,是不是发生了这种情况?当一个平面的上限接触另一个平面的下限时,是不是发生了这种情况?
在我贴出的代码中,我将数据集减少到了只有一些元素。我只使用简单的散点图和线条图,但由于数据集的大小(也许是mplot3d的限制?),我无法用它来发现我正在寻找的趋势。
dates = [20110101,20110104,20110105,20110106,20110107,20110108,20110111,20110112]

zAxis0= [       0,       0,       0,       0,       0,       0,       0,       0]
Actual= [    1132,    1184,    1177,     950,    1066,    1098,    1116,    1211]

zAxis1= [       1,       1,       1,       1,       1,       1,       1,       1]
Tops1 = [    1156,    1250,    1156,    1187,    1187,    1187,    1156,    1156]
Mids1 = [    1125,    1187,    1125,    1156,    1156,    1156,    1140,    1140]
Lows1 = [    1093,    1125,    1093,    1125,    1125,    1125,    1125,    1125]

zAxis2= [       2,       2,       2,       2,       2,       2,       2,       2]
Tops2 = [    1125,    1125,    1125,    1125,    1125,    1250,    1062,    1250]
Mids2 = [    1062,    1062,    1062,    1062,    1062,    1125,    1000,    1125]
Lows2 = [    1000,    1000,    1000,    1000,    1000,    1000,     937,    1000]

zAxis3= [       3,       3,       3,       3,       3,       3,       3,       3]
Tops3 = [    1250,    1250,    1250,    1250,    1250,    1250,    1250,    1250]
Mids3 = [    1187,    1187,    1187,    1187,    1187,    1187,    1187,    1187]
Lows3 = [    1125,    1125,    1000,    1125,    1125,    1093,    1093,    1000]

import matplotlib.pyplot
from mpl_toolkits.mplot3d import Axes3D

fig = matplotlib.pyplot.figure()
ax  = fig.add_subplot(111, projection = '3d')

#actual values
ax.scatter(dates, zAxis0, Actual, color = 'c', marker = 'o')

#Upper limits, Lower limts, and Mid-range for the FIRST plane
ax.plot(dates, zAxis1, Tops1, color = 'r')
ax.plot(dates, zAxis1, Mids1, color = 'y')
ax.plot(dates, zAxis1, Lows1, color = 'b')

#Upper limits, Lower limts, and Mid-range for the SECOND plane
ax.plot(dates, zAxis2, Tops2, color = 'r')
ax.plot(dates, zAxis2, Mids2, color = 'y')
ax.plot(dates, zAxis2, Lows2, color = 'b')

#Upper limits, Lower limts, and Mid-range for the THIRD plane
ax.plot(dates, zAxis3, Tops3, color = 'r')
ax.plot(dates, zAxis3, Mids3, color = 'y')
ax.plot(dates, zAxis3, Lows3, color = 'b')

#These two lines are just dummy data that plots transparent circles that
#occpuy the "wall" behind my actual plots, so that the last plane appears
#floating in 3D rather than being pasted to the plot's background
zAxis4= [       4,       4,       4,       4,       4,       4,       4,       4]
ax.scatter(dates, zAxis4, Actual, color = 'w', marker = 'o', alpha=0)

matplotlib.pyplot.show()

我看到了这个图表,但它并没有帮助我看到任何相关性。我不是数学家或科学家,所以我真正需要的是帮助选择可视化数据的格式。在mplot3d中是否有有效的方法来展示这个?还是你会使用MayaVis?在任一情况下,你会使用哪个库和类别?谢谢提前的帮助。

2
如果你正在寻找相关性,3D 可能不是最好的选择。透视会妨碍解释。相反,你可能想使用分面图、叠加图和散点图。 - daedalus
2个回答

7

就您问题中的图形化部分(而非编程)进行评论,我制作了一些示例分面图表,以建议您使用更好的方式来探索数据。

library("lubridate")
library("ggplot2")
library("reshape2")

dates <- c("2011-01-01","2011-01-04","2011-01-05",
           "2011-01-06","2011-01-07","2011-01-08",
           "2011-01-11","2011-01-12")
dates <- ymd(dates)

Actual<- c(    1132,    1184,    1177,     950,    1066,    1098,    1116,    1211,
               1132,    1184,    1177,     950,    1066,    1098,    1116,    1211,
               1132,    1184,    1177,     950,    1066,    1098,    1116,    1211)
z     <- c(       1,       1,       1,       1,       1,       1,       1,       1,
                  2,       2,       2,       2,       2,       2,       2,       2,
                  3,       3,       3,       3,       3,       3,       3,       3)
Tops <- c(    1156,    1250,    1156,    1187,    1187,    1187,    1156,    1156,
              1125,    1125,    1125,    1125,    1125,    1250,    1062,    1250,
              1250,    1250,    1250,    1250,    1250,    1250,    1250,    1250)
Mids <- c(    1125,    1187,    1125,    1156,    1156,    1156,    1140,    1140,
              1062,    1062,    1062,    1062,    1062,    1125,    1000,    1125,
              1187,    1187,    1187,    1187,    1187,    1187,    1187,    1187)
Lows <- c(    1093,    1125,    1093,    1125,    1125,    1125,    1125,    1125,
              1000,    1000,    1000,    1000,    1000,    1000,     937,    1000,
              1125,    1125,    1000,    1125,    1125,    1093,    1093,    1000)

df <- data.frame( cbind(z, dates, Actual, Tops, Mids, Lows))

dfm <- melt(df, id.vars=c("z", "dates", "Actual"))

在第一个例子中,细蓝线是实际值,叠加在每个 z 轴的三个级别上。
p <- ggplot(data = dfm,
            aes(x = dates,
                y = value,
                group = variable,
                colour = variable)
            ) + geom_line(size = 3) +
                facet_grid(variable ~ z) +
                geom_point(aes(x = dates,
                               y = Actual),
                           colour = "steelblue",
                           size = 3) +
                               geom_line(aes(x = dates,
                                             y = Actual),
                                         colour = "steelblue",
                                         size = 1) +
                                             theme_bw()
p

线性图表

在第二组中,每个面板都有一个散点图,显示实际值与各自在三个z轴(顶部,中部,低部)上的水平之间的关系。

p <- ggplot(data = dfm,
            aes(x = Actual,
                y = value,
                group = variable,
                colour = variable)
            ) + geom_point(size = 3) +
                geom_smooth() +
                facet_grid(variable ~ z) +
                theme_bw()
p

correlation


谢谢,gauden。关于第二组数据(带有灰色信封的绘图),在R中这种图表被称为什么?您知道Python/matplotlib相应的名称吗?我一直在看matplotlib的画廊,但似乎找不到相似的内容。 - Zambi
1
@Zambi,我很高兴发布R代码。您可能希望将“R”标签添加到您的问题中,以增加可能的答案数量。我不确定第二个图有一个特定的名称。它是由两个变量(z轴和级别)分面的散点图集合。该线是拟合的“loess”曲线,云代表标准误差。我使用ggplot2来生成此图。 - daedalus
2
将数据分成子集并绘制2D子图网格的这种方法通常被称为“facets”(ggplot [Wickham])或“small multiples”(Tufte)或“conditioning plots”,常简称为“coplots”(lattice/Trellis [Cleveland,Chambers,Sarkar])。 - Ben Bolker

2
谢谢,高登。实际上,R是我研究的一部分,我已经安装了它,但只是没有按教程做得够深入。除非违反StackOverFlow的规定,否则我希望能看到你的R代码。
我已经尝试过2D表示,但在许多情况下,Tops1/Tops2/Tops3(以及Lows类似)的值将相等,因此线条重叠并互相遮挡。这就是为什么我正在尝试3D选项。你提出的3个2D图形面板的想法是一个我没有探索过的好建议。
我会尝试一下,但我认为3D图形会给我更清晰的图片,特别是线框/网格图,它将显示值的收敛,并且当网格线开始形成峰或谷时,我会看到蓝点在三维空间中漂浮的位置。我只是无法让它工作。
我尝试调整 matplotlib的Wireframe示例,但我得到的图形根本不像一个线框图。
以下代码显示了我从中获取的信息 enter image description here,其中仅包含两个数据元素(Tops1和Tops2):
dates = [20110101,20110104,20110105,20110106,20110107,20110108,20110111,20110112]

zAxis0= [       0,       0,       0,       0,       0,       0,       0,       0]
Actual= [    1132,    1184,    1177,     950,    1066,    1098,    1116,    1211]

zAxis1= [       1,       1,       1,       1,       1,       1,       1,       1]
Tops1 = [    1156,    1250,    1156,    1187,    1187,    1187,    1156,    1156]
Mids1 = [    1125,    1187,    1125,    1156,    1156,    1156,    1140,    1140]
Lows1 = [    1093,    1125,    1093,    1125,    1125,    1125,    1125,    1125]

zAxis2= [       2,       2,       2,       2,       2,       2,       2,       2]
Tops2 = [    1125,    1125,    1125,    1125,    1125,    1250,    1062,    1250]
Mids2 = [    1062,    1062,    1062,    1062,    1062,    1125,    1000,    1125]
Lows2 = [    1000,    1000,    1000,    1000,    1000,    1000,     937,    1000]

zAxis3= [       3,       3,       3,       3,       3,       3,       3,       3]
Tops3 = [    1250,    1250,    1250,    1250,    1250,    1250,    1250,    1250]
Mids3 = [    1187,    1187,    1187,    1187,    1187,    1187,    1187,    1187]
Lows3 = [    1125,    1125,    1000,    1125,    1125,    1093,    1093,    1000]

import matplotlib.pyplot
from mpl_toolkits.mplot3d import Axes3D

fig = matplotlib.pyplot.figure()
ax  = fig.add_subplot(111, projection = '3d')

####example code from: http://matplotlib.sourceforge.net/mpl_toolkits/mplot3d/tutorial.html#wireframe-plots
#from mpl_toolkits.mplot3d import axes3d
#import matplotlib.pyplot as plt
#import numpy as np

#fig = plt.figure()
#ax = fig.add_subplot(111, projection='3d')
#X, Y, Z = axes3d.get_test_data(0.05)
#ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)

#plt.show()

X, Y, Z =  dates, Tops1, Tops2 
ax.plot_wireframe(X, Y, Z, rstride=1, cstride=1, color = 'g')

matplotlib.pyplot.show()

+1 鼓励尝试。我希望其他人能够加入并提供帮助,我已经收藏了这个问题以便关注后续的进展。 - daedalus

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