Как преобразовать значения контура и построить график на поверхности трехмерной сферыPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как преобразовать значения контура и построить график на поверхности трехмерной сферы

Сообщение Anonymous »

Я пытаюсь использовать matplotlib shapef для создания контурного графика данных о температуре. Затем я хотел бы сопоставить эти данные с трехмерной сферой. Я использую vpython для рендеринга изображения. У меня проблема в том, что полигоны не генерируются по всей поверхности сферы, а также в данных много пробелов. Может кто-нибудь объяснить, как этого можно достичь?

Код: Выделить всё

from vpython import vector

import numpy as np
from matplotlib import pyplot as plt

from vpython import triangle, vertex, vec

from scipy.interpolate import griddata

def spherical_to_cartesian(lat, lon, radius=3):
lons = np.radians(lon)
lats = np.radians(lat)

x = radius * np.cos(lats) * np.cos(lons)
y = radius * np.cos(lats) * np.sin(lons)
z = radius * np.sin(lats)
return np.array([x, y, z])

shape = (721, 1440)

lats = np.linspace(-90, 90, shape[0])
lons = np.linspace(-180, 180, shape[1])

min_temp = -30
max_temp = 50
temps = np.random.uniform(min_temp, max_temp, size=shape)

lons_grid, lats_grid = np.meshgrid(lons, lats)

new_lons = np.linspace(lons.min(), lons.max(), 72)  # 72 points in longitude
new_lats = np.linspace(lats.min(), lats.max(), 36)  # 36 points in latitude
new_lons_grid, new_lats_grid = np.meshgrid(new_lons, new_lats)

radius = 3

lats_flat = lats_grid.flatten()
lons_flat = lons_grid.flatten()
temps_flat = temps.flatten()

coarse_temps = griddata(
(lons_flat, lats_flat),
temps_flat,
(new_lons_grid, new_lats_grid),
method='linear'  # Use 'linear', 'nearest', or 'cubic' as needed
)

norm = plt.Normalize(coarse_temps.min(), vmax=coarse_temps.max())

cmap = plt.get_cmap("inferno", 100)

levels = 100

levels = np.linspace(coarse_temps.min(), coarse_temps.max(), levels + 1)

bucketed_data = np.digitize(coarse_temps, levels) - 1

fig, ax = plt.subplots()
contours = ax.contourf(new_lons_grid, new_lats_grid, bucketed_data, levels=np.arange(len(levels)))
plt.close(fig)

def create_polygon(region, temp_color):
if len(region) < 3:
# Can't form a polygon with fewer than 3 points
return

# Calculate the centroid of the region
centroid = vec(sum(p[0] for p in region) / len(region),
sum(p[1] for p in region) / len(region),
sum(p[2] for p in region) / len(region))

# Tessellate the region into triangles
for i in range(len(region) - 1):
v0 = vec(*region[i])
v1 = vec(*region[i + 1])
triangle(
v0=vertex(pos=v0, color=temp_color),
v1=vertex(pos=v1, color=temp_color),
v2=vertex(pos=centroid, color=temp_color)
)

v0 = vec(*region[-1])
v1 = vec(*region[0])
triangle(
v0=vertex(pos=v0, color=temp_color),
v1=vertex(pos=v1, color=temp_color),
v2=vertex(pos=centroid, color=temp_color)
)

def split_contours(segs, kinds=None):
if kinds is None:
return segs  # nothing to be done
new_segs = []
for i, seg in enumerate(segs):
segkinds = kinds[i]
boundaries = [0] + list(np.nonzero(segkinds == 79)[0])
for b in range(len(boundaries) - 1):
new_segs.append(seg[boundaries[b] + (1 if b > 0 else 0):boundaries[b + 1]])
return new_segs

allsegs = contours.allsegs
allkinds = contours.allkinds
colors = cmap(norm(coarse_temps))
rgb_colors = [
tuple(int(c * 255) for c in color[:3])
for color in colors.reshape(-1, colors.shape[-1])
]
for clev in range(len(contours.allsegs)):
kinds = None if allkinds is None else allkinds[clev]
segs = split_contours(allsegs[clev], kinds)
rgb = cmap(clev)[:3]
coords = [spherical_to_cartesian(lat, lon, radius=3) for seg in segs for lon, lat in seg]
temp_color = vector(*rgb)
create_polygon(coords, temp_color)

import time
while True:
time.sleep(0.03)
Вот как отображается сфера. Я хотел бы, чтобы контуры отображались на поверхности сферы, как если бы 2D-контуры были проецированы на 3D-поверхность.
Изображение


Подробнее здесь: https://stackoverflow.com/questions/792 ... -3d-sphere
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»