contourf 上的不连续、非单调 x 轴

Discontinuos, non-monotonic x-axis on contourf

我正在绘制球坐标中的 3D 形状。为了旋转它,我将 phi 值移动 30 度,如以下代码中所示 phi_linphi_rot。我希望面板 4 中的结果与面板 2 具有相同的分布,但严格向右移动了 30 度。

我想,问题在于绘图函数 countorf 无法处理 phi_rot 输入向量,因为它是非单调的。可以在面板 3 中看到移动的不连续性。我该如何克服这个问题?

这里是工作代码:

import glob
import math
import numpy as np
import pandas as pd

import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.colors import LightSource
%matplotlib inline

import itertools

def ellips(THETA,PHI):
    """
    #Definiton of the ellipsoid
    # from https://arxiv.org/pdf/1104.5145.pdf
    """
    a=1; b=2; c=3
    R = (a*b*c) / np.sqrt(b**2*c**2*np.cos(THETA)**2 + c**2*a**2*np.sin(THETA)**2*np.cos(PHI)**2 + a**2*b**2*np.sin(THETA)**2*np.sin(PHI)**2)
    return np.array(R)


nth=13
theta = np.linspace(0, np.pi, nth)

#length = 13
phi_lin=[-180,-150,-120,-90,-60,-30,0,30,60,90,120,150,180]
phi_rot=[-150,-120,-90,-60,-30,0,30,60,90,120,150,180,-180]

THETA_lin, PHI_lin = np.meshgrid(theta, phi_lin)
THETA_rot, PHI_rot = np.meshgrid(theta, phi_rot)

THETA_deg_lin=[el*180/np.pi for el in THETA_lin]
THETA_deg_rot=[el*180/np.pi for el in THETA_rot]
PHI_deg_lin=[el for el in PHI_lin]
PHI_deg_rot=[el for el in PHI_rot]

fig1, ax = plt.subplots(2,2, figsize=(15,15), constrained_layout=True)

ax[0,0].plot(PHI_deg_lin, "o")
ax[0,0].set_xlabel("# element")
ax[0,0].set_ylabel('phi [DEG]')
ax[0,0].set_title("initial coordinates")

ax[0,1].contourf(PHI_deg_lin, THETA_deg_lin, ellips(THETA_deg_lin,PHI_deg_lin).reshape(len(phi_lin),nth))
ax[0,1].set_xlabel('phi [DEG]')
ax[0,1].set_ylabel('theta [DEG]')
ax[0,1].set_title("Original ellipsoind in spherical coordinates")

ax[1,0].plot(PHI_deg_rot, "o")
ax[1,0].set_xlabel("# element")
ax[1,0].set_ylabel('phi [DEG]')
ax[1,0].set_title("shifted coordinates")

ax[1,1].contourf(PHI_deg_rot, THETA_deg_rot, ellips(THETA_deg_rot,PHI_deg_rot).reshape(len(phi_rot),nth))
ax[1,1].set_xlabel('phi [DEG]')
ax[1,1].set_ylabel('theta [DEG]')
ax[1,1].set_title("Original ellipsoind in spherical coordinates")

和输出:

更新:我试图用旋转坐标创建插值函数 z=f(x,y) 并绘制新的 z:

from scipy import interpolate
    
i2d = interpolate.interp2d(theta, phi_rot, ellips(THETA_deg_rot,PHI_deg_rot))
    znew = i2d(theta,phi_lin)
    
    
ax[1,1].contourf(PHI_deg_rot, THETA_deg_rot,znew.reshape(len(phi_rot),nth))

如您在以下输出中所见,发生了移位,但非线性间隔的 x 轴阻止了平滑的轮廓:

知道如何解决吗?

该解决方案的灵感来自 this post

由于contourf不接受non-linearly-spaced轴,需要对旋转后的数据进行插值

from scipy import interpolate

i2d = interpolate.interp2d(theta, phi_rot, ellips(THETA_deg_rot,PHI_deg_rot))

在同一轴上对其进行评估(此时 lin 或 rot 无关紧要)

znew = i2d(theta,phi_lin)

并使用 tricontourf 和适当的级别数

绘制它
ax[1,1].tricontourf(np.array(PHI_deg_rot).reshape(-1), np.array(THETA_deg_rot).reshape(-1),znew.reshape(-1),10)

输出是预期的: