79282137

Date: 2024-12-15 10:28:56
Score: 1
Natty:
Report link

With thanks to misho88 on reddit who posted this and advised to look at using matplotlib.tri.Triangulation and tricontourf the following works:

import numpy as np
import matplotlib.tri as tri
from vpython import vector, triangle, vertex, vec
import matplotlib.pyplot as plt


# Function to convert spherical to Cartesian coordinates
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)
new_lats = np.linspace(lats.min(), lats.max(), 36)
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()

# Randomly sample a subset of the points
num_samples = 10000  # Adjust this number to control triangle density
indices = np.random.choice(len(lats_flat), size=num_samples, replace=False)
lats_sampled = lats_flat[indices]
lons_sampled = lons_flat[indices]
temps_sampled = temps_flat[indices]

triang = tri.Triangulation(lons_sampled, lats_sampled)


fig, ax = plt.subplots()
contour = ax.tricontourf(triang, temps_sampled, levels=100, cmap='inferno')
plt.colorbar(contour)
plt.close(fig)

for tri_indices in triang.triangles:

    vertices = []
    for idx in tri_indices:
        xi, yi, zi = spherical_to_cartesian(lats_sampled[idx], lons_sampled[idx])
        temp = temps_sampled[idx]
        color_value = plt.cm.inferno((temp - min_temp) / (max_temp - min_temp))
        vertices.append(vertex(pos=vector(xi, yi, zi), color=vec(*color_value[:3])))
    triangle(v0=vertices[0], v1=vertices[1], v2=vertices[2])


import time
while True:
    time.sleep(0.03)

enter image description here

Reasons:
  • Blacklisted phrase (0.5): thanks
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: John