Griddata 和 Contourf 生成步数/级别增加的工件

问题描述

我正在使用 SciPy Griddata 以笛卡尔形式插入数据,然后使用具有极坐标投影的轮廓绘制这些数据。当笛卡尔插值数据用轮廓绘制时,没有伪影。然而,当投影是极坐标时,伪影会随着“级别”的增加而发展。

伪影是在陡峭梯度区域附近形成的多边形或射线。下面的代码绘制了天空与月亮的亮度。图形级别为“12”就没有问题。工件以“25”的图形级别发展。我想要的等级是 80 或更高 - 这显示了可怕的文物。以下是一晚的真实数据示例。这些伪影总是发生。查看带有 Levels = 12Levels = 80

的图像
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata


gridsize =150
graphlevels =12

plt.figure(figsize=(12,10))
ax = plt.subplot(111,projection='polar')


x = [72.90,68.00,59.14,44.38,29.63,63.94,59.68,51.92,38.98,26.03,47.34,44.20,38.46,28.89,19.31,23.40,20.40,15.34,10.28,-0.18,-0.14,-0.09,-0.04,0.02,-25.39,-23.66,-20.57,-15.40,-10.23,-47.56,-44.34,-38.54,-28.89,-19.22,-64.01,-59.68,-51.89,-38.90,-25.90,-72.77,-67.84,-58.98,-44.21,-29.44,-72.75,-67.83,-58.96,-44.18,-29.41,-59.63,-51.82,-38.83,-25.84,-47.42,-44.20,-38.40,-28.76,-19.12,-23.40,-20.32,-15.19,-10.08,0.27,0.25,0.23,0.20,23.92,20.80,15.63,10.46,47.93,44.67,38.86,29.17,19.48,64.40,60.03,52.20,39.18,26.15,73.08,68.12,59.26,44.47,29.68,-4.81]
y = [12.93,12.01,10.38,7.67,4.99,37.03,34.49,29.93,22.33,14.77,56.60,52.75,45.82,34.26,22.72,64.60,56.14,42.02,27.90,73.66,68.67,44.68,69.12,64.45,56.00,41.92,27.84,56.26,52.45,45.56,34.08,22.61,36.59,34.11,29.61,22.11,14.62,12.48,11.62,10.04,7.43,4.83,-13.33,-12.31,-10.78,-8.21,-5.58,-34.84,-30.36,-22.87,-15.36,-57.04,-53.20,-46.31,-34.83,-23.34,-65.20,-56.72,-42.62,-28.53,-69.33,-60.31,-45.31,-30.31,-65.09,-56.63,-42.55,-28.47,-56.81,-52.99,-46.13,-34.69,-23.23,-36.99,-34.53,-30.08,-22.66,-15.22,-12.73,-11.93,-10.44,-7.94,-5.40,-1.22,]
skybrightness = [19.26,19.21,19.65,19.40,19.26,19.23,19.43,19.57,19.52,19.19,19.33,19.68,19.50,19.29,19.45,18.98,19.28,19.46,19.54,19.22,19.03,19.18,19.35,19.37,19.08,18.99,19.36,18.79,18.85,19.13,19.17,19.05,18.51,18.64,18.88,18.92,18.93,18.12,18.34,18.72,18.82,18.74,18.22,18.46,18.76,18.26,18.13,18.24,18.58,17.30,18.38,18.08,17.68,18.65,18.23,18.70,18.52,18.83,18.18,19.01,19.02,19.07,19.20,19.27,19.06,19.30,18.94]

xgrid = np.linspace(min(x),max(x),gridsize)
ygrid = np.linspace(min(y),max(y),gridsize)

xgrid,ygrid = np.meshgrid(xgrid,ygrid,indexing='ij')

nsb_grid = griddata((x,y),skybrightness,(xgrid,ygrid),method='linear')

r = np.sqrt(xgrid**2 + ygrid**2)
theta = np.arctan2(ygrid,xgrid)

plt.rc('ytick',labelsize=16)
ax.set_facecolor('#eeddcc')

colors = plt.cm.get_cmap('RdYlBu')
levels,steps = np.linspace(min(skybrightness),max(skybrightness)+0.3,graphlevels,retstep=True)
ticks = np.linspace(min(skybrightness),12)

cax = ax.contourf(theta,r,nsb_grid,levels=levels,cmap=colors)

cbar = plt.colorbar(cax,fraction=0.046,pad=0.04,ticks=ticks)
cbar.set_label(r'mag/arcsec$^2$')
ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)
ax.set_rmax(75)
ax.set_yticks(range(10,80,20))
ax.set_xticklabels([r'N',r'NE',r'E',r'SE',r'S',r'SW',r'W',r'NW'])
ax.grid(alpha=0.3)
plt.savefig('StackOverflowHELP.png')

解决方法

我将把我的问题和这个答案留在 StackOverflow 上……因为我确实从 Matploblib 的开发人员那里得到了答案。问题是 Contourf 。在尝试以极坐标维度投影数据时,循环边界处的多边形重叠和延伸会导致问题。避免这种情况的唯一方法是在边界处添加点。引用开发商的话:

解决方法需要大量工作,并且必须针对每个特定问题进行调整,因此距离理想还有很长的路要走。我们(Matplotlib)在这些情况下应该做得更好。在三角剖分中插入额外的点不是正确的方法,我们应该改正穿过不连续点的线/多边形以提供通用解决方案。

请参阅 https://github.com/matplotlib/matplotlib/issues/20060 以了解完整讨论

我确定的答案是在笛卡尔空间中插入和渲染结果。然后我用轴和标签格式化一个空的极坐标图以覆盖在顶部......然后继续我的生活!

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata


gridsize =150
graphlevels = 200

fig = plt.figure(figsize=(12,10))

ax = fig.add_subplot(111,aspect='equal')
pax = fig.add_subplot(111,projection='polar')
pax.set_facecolor('none')
ax.set_axis_off()
ax.set_xlim([-75,75])
ax.set_ylim([-75,75])

x = [72.90,68.00,59.14,44.38,29.63,63.94,59.68,51.92,38.98,26.03,47.34,44.20,38.46,28.89,19.31,23.40,20.40,15.34,10.28,-0.18,-0.14,-0.09,-0.04,0.02,-25.39,-23.66,-20.57,-15.40,-10.23,-47.56,-44.34,-38.54,-28.89,-19.22,-64.01,-59.68,-51.89,-38.90,-25.90,-72.77,-67.84,-58.98,-44.21,-29.44,-72.75,-67.83,-58.96,-44.18,-29.41,-59.63,-51.82,-38.83,-25.84,-47.42,-44.20,-38.40,-28.76,-19.12,-23.40,-20.32,-15.19,-10.08,0.27,0.25,0.23,0.20,23.92,20.80,15.63,10.46,47.93,44.67,38.86,29.17,19.48,64.40,60.03,52.20,39.18,26.15,73.08,68.12,59.26,44.47,29.68,-4.81]
y = [12.93,12.01,10.38,7.67,4.99,37.03,34.49,29.93,22.33,14.77,56.60,52.75,45.82,34.26,22.72,64.60,56.14,42.02,27.90,73.66,68.67,44.68,69.12,64.45,56.00,41.92,27.84,56.26,52.45,45.56,34.08,22.61,36.59,34.11,29.61,22.11,14.62,12.48,11.62,10.04,7.43,4.83,-13.33,-12.31,-10.78,-8.21,-5.58,-34.84,-30.36,-22.87,-15.36,-57.04,-53.20,-46.31,-34.83,-23.34,-65.20,-56.72,-42.62,-28.53,-69.33,-60.31,-45.31,-30.31,-65.09,-56.63,-42.55,-28.47,-56.81,-52.99,-46.13,-34.69,-23.23,-36.99,-34.53,-30.08,-22.66,-15.22,-12.73,-11.93,-10.44,-7.94,-5.40,-1.22,]
skybrightness = [19.26,19.21,19.65,19.40,19.26,19.23,19.43,19.57,19.52,19.19,19.33,19.68,19.50,19.29,19.45,18.98,19.28,19.46,19.54,19.22,19.03,19.18,19.35,19.37,19.08,18.99,19.36,18.79,18.85,19.13,19.17,19.05,18.51,18.64,18.88,18.92,18.93,18.12,18.34,18.72,18.82,18.74,18.22,18.46,18.76,18.26,18.13,18.24,18.58,17.30,18.38,18.08,17.68,18.65,18.23,18.70,18.52,18.83,18.18,19.01,19.02,19.07,19.20,19.27,19.06,19.30,18.94]

xgrid = np.linspace(min(x),max(x),gridsize)
ygrid = np.linspace(min(y),max(y),gridsize)

xgrid,ygrid = np.meshgrid(xgrid,ygrid,indexing='ij')

nsb_grid = griddata((x,y),skybrightness,(xgrid,ygrid),method='linear')

plt.rc('ytick',labelsize=16) #colorbar font

colors = plt.cm.get_cmap('RdYlBu')
levels,steps = np.linspace(min(skybrightness),max(skybrightness)+0.3,graphlevels,retstep=True)
ticks = np.linspace(min(skybrightness),12)

cax = ax.contourf(xgrid,nsb_grid,levels=levels,cmap=colors)

cbar = plt.colorbar(cax,fraction=0.046,pad=0.04,ticks=ticks)
cbar.set_label(r'mag/arcsec$^2$')
pax.set_theta_zero_location('N')
pax.set_theta_direction(-1)
pax.set_rmax(75)
pax.set_yticks(range(10,80,20))
pax.set_xticklabels([r'N',r'NE',r'E',r'SE',r'S',r'SW',r'W',r'NW'])
pax.grid(alpha=0.3)