Как бы вы представили следующие 3D-данные в Matplotlib или Mayavi?

У меня есть большой набор данных, которые я пытаюсь представить в 3D, надеясь обнаружить закономерность. Я потратил довольно много времени на чтение, исследование и кодирование, но потом понял, что моя главная проблема НЕ в программировании, а на самом деле выбор способа визуализации данных.

mplot3d от Matplotlib предлагает множество опций (каркас, контур, контур с заливкой и т. д.), как и MayaVi. Но есть так много вариантов (и каждый со своей кривой обучения), что я практически теряюсь и не знаю, с чего начать! Итак, мой вопрос, по сути, заключается в том, какой метод построения графика ВЫ бы использовали, если бы вам пришлось иметь дело с этими данными?

Мои данные основаны на дате. Для каждого момента времени я рисую значение (список «Фактическое»).

Но для каждого момента времени у меня также есть верхний предел, нижний предел и точка среднего диапазона. Эти пределы и средние точки основаны на семени, в разных плоскостях.

Я хочу определить точку или определить закономерность, когда или до того, как в моем «фактическом» чтении произойдет серьезное изменение. Когда встречаются верхние пределы на всех планах? Или подойти друг к другу? Это когда фактическое значение касается верхнего/среднего/нижнего предела? Когда Верхние в одном плане соприкасаются с Нижними в другом плане?

В коде, который я вставляю, я сократил набор данных до нескольких элементов. Я просто использую простые точечные и линейные графики, но из-за размера набора данных (и, возможно, ограничений 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? В любом случае, какие библиотеки и классы ВЫ бы использовали?

Заранее спасибо.


person Zambi    schedule 26.05.2012    source источник
comment
Если вы ищете корреляции, 3D может быть не лучшим способом. Перспектива мешает интерпретации. Вместо этого вы можете использовать фасетные диаграммы, избыточные графики и диаграммы рассеяния.   -  person daedalus    schedule 26.05.2012


Ответы (2)


Чтобы прокомментировать часть вашего вопроса о визуализации (а не о программировании), я смоделировал несколько примеров фасетных графиков, чтобы предложить альтернативы, которые вы можете использовать для изучения своих данных.

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

корреляция

person daedalus    schedule 26.05.2012
comment
Спасибо, Гауден. Что касается второго набора (тот, что с графиком, обведенным серым конвертом), то как называется такая диаграмма в R? А знаете ли вы название эквивалента Python/matplotlib? Я просматривал галерею matplotlib и не нашел ничего похожего. - person Zambi; 27.05.2012
comment
@Zambi Я рад опубликовать код R. Вы можете добавить тег R к своему вопросу, чтобы увеличить количество возможных ответов. Я не уверен, что у второго сюжета есть конкретное название. Это набор диаграмм рассеяния, разделенных двумя переменными (ось z и уровни). Линия представляет собой подогнанную кривую loess, а облако представляет собой стандартную ошибку. Для этого я использую пакет ggplot2. - person daedalus; 27.05.2012
comment
Некоторые распространенные названия для этого подхода к разбиению данных на подмножества и построению сетки двумерных подграфиков — фасеты (ggplot [Wickham]), малые кратные (Tufte) или кондиционирующие графики, часто сокращаемые до coplot (решетка/решетка [Cleveland, Chambers, Sarkar ]) - person Ben Bolker; 27.05.2012

Спасибо, Гауден. На самом деле R был частью моего исследования, и я установил его, но недостаточно подробно изучил руководство. Если это не противоречит правилам StackOverFlow, я был бы признателен, если бы увидел ваш код R.

Я уже пробовал 2D-представления, но во многих случаях значения для Вершин 1/Вершин 2/Вершин 3 (и аналогично для Минимумов) будут одинаковыми, поэтому линии в конечном итоге перекрываются и закрывают друг друга. Вот почему я пробую вариант 3D. Ваша идея о трех панелях 2D-графиков — отличное предложение, которое я не исследовал.

Я попробую, но я думал, что 3D-график даст мне более четкую картину, особенно каркасный/сетчатый график, который покажет сходящиеся значения, и я увижу синюю точку, плавающую в 3D-пространстве в точке, когда линии на каркасе начинают формировать пик или впадину. Я просто не могу заставить его работать.

Я попытался адаптировать пример Wireframe из matplotlib, но график получаю совсем не похоже на каркас.

Вот что я получаю из приведенного ниже кода введите здесь описание изображениявсего с двумя элементами данных (Tops1 и Топы2):

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()
person Zambi    schedule 27.05.2012
comment
+1 за эксперимент. Я надеюсь, что другие вмешаются, чтобы помочь, и я выбрал вопрос, чтобы посмотреть, что получится. - person daedalus; 27.05.2012