Как наложить контурный график на трехмерный поверхностный график с помощью matplotlib или plotly? - PullRequest
2 голосов
/ 22 октября 2019

У меня есть трехмерный график поверхности, который показывает координаты x и y и глубины. У меня также есть двухмерный контурный график с координатами x и y и заполненными контурами в разных местах. Если я знаю глубину в координатах на графике контура, могу ли я показать контуры на трехмерном графике поверхности?

Я создал трехмерный график поверхности, используя plotly скод ниже:

import plotly.graph_objects as go
import oceansdb
import numpy as np 
import matplotlib.pyplot as plt

Xa = np.linspace(29.005,29.405,200)
Ya = np.linspace(-93.6683,-93.2683,200)

db = oceansdb.ETOPO()
dcont = db['topography'].extract(lat=Xa, lon=Ya)
depth = dcont['height']

fig = go.Figure(data=[go.Surface(z=depth, x=Xa, y=Ya)])
fig.show()

Скажите, что мой контурный график может быть создан с кодом ниже:

X = np.array([29.1,29.15,29.2,29.25])
Y = np.array([-93.5,-93.45,-93.4,-93.35])
r = np.array([0,0,0,2,3,0,0,6,7,8,9,1,9,0,0,0])

plt.figure()
plt.contourf(X,Y,r.reshape(len(X),len(Y)))
plt.show()

Предполагая, что глубина в каждом месте может быть определена с помощью модуля oceansdbМожно ли наложить контурный график на график поверхности на правильной глубине?

1 Ответ

0 голосов
/ 25 октября 2019

Используя matplotlib, можно получить краткий ответ «да», но есть два , но с, у вас есть лицо:

  1. Визуализация трехмерных данных затруднена, и перекрытие нескольких наборов данных болеечасто, чем не путают за простейшими случаями
  2. Matplotlib имеет 2d рендерер, поэтому даже если вы можете построить несколько объектов на одном и том же 3d рисунке, часто будут артефакты рендеринга (в частности, два объекта обычно могут быть либополностью впереди или позади друг друга).

Ключевые методы, которые вам нужны: Axes3D.contour или Axes3D.contourf. Вот они в действии с вашими примерами:

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D  # this enables 3d axes

X = np.array([29.1,29.15,29.2,29.25]) 
Y = np.array([-93.5,-93.45,-93.4,-93.35]) 
r = np.array([0,0,0,2,3,0,0,6,7,8,9,1,9,0,0,0]).reshape(X.size, Y.size)

# plot your 2d contourf for reference 
fig,ax = plt.subplots() 
ax.contourf(X, Y, r) 

# plot in 3d using contourf
fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 
ax.contourf(X, Y, r) 

# plot in 3d using contour
fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 
ax.contour(X, Y, r) 

plt.show() 

Вот ваш 2d contourf сюжет: 2d contour plot according to OP's original code

Вот версия 3d contourf:3d-embedded contour plot where each level is filled with horizontal planes

А вот 3d contour версия: 3d-embedded contour plot where only level lines are plotted

Как вы можете видеть разницу между двумя последнимичто contourf также строит горизонтальные плоскости для каждого уровня (точно так же, как террасы ), тогда как contour строит только сами линии уровня.

Поскольку повторные графики, использующие одни и те же оси, будут накапливать графикиничто не мешает вам наложить одну из этих трехмерных контурных диаграмм на исходную поверхность. Однако, в соответствии с моими предыдущими предупреждениями, вам придется следить за тем, правильно ли отображаются контуры на поверхности (под всеми углами обзора), и даже в этом случае результат может быть не таким прозрачным для передачи информации. Лично я склонен находить contourf гораздо проще для понимания, чем contour на трехмерном графике, но я подозреваю, что если мы поместим их поверх графиков с полной поверхностью, последний получится лучше.

...