matplotlib 未填充,极坐标图边界附近有白色空隙

sczxawaw  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(88)

我尝试使用 matplotlibcontourf创建一个 polar plot,但它在圆边界附近产生了一些未填充的区域,仅在图的某些侧面。这个问题似乎是一个常见的问题,我们可以在许多例子中看到。1的数据。


的数据
起初,我认为它可能需要一些插值,并尝试基于一些可用的方法进行插值,例如。但我无法画出完美的情节。使用 SciPy griddatalinear 方法进行插值解决了主要问题,但在图上产生了一些阴影,而 cubic 方法导致了一些不适当的颜色(显示结果不正确)。



最后,我猜这个问题可能与我指定的图形大小和我使用的dpi有关。在低dpi的情况下,它被治愈了很多,但会得到低质量的PNG。当我用dpi=600停用指定图形大小(# plt.rcParams["figure.figsize"] = (19.2, 9.6))的相关行时,它显示得相当正确,但不是所需的图形大小。


主要问题是如何解决保存文件的问题,以及所需的指定图形大小和dpi?必须说明的是,问题出现在保存的文件上。

除了解决问题的答案,我将不胜感激,如果任何关于这些问题的答案太:

  • 为什么会这样?
  • 为什么它只发生在情节的某些方面?在这个例子中,问题只出现在季度的右侧,而不是上行。这个问题让我怀疑数据是否正确地显示在圆圈上以供分析。可以吗?
  • 我们需要对这些数据进行插值吗?如果是这样的话,哪些算法将是最好的,它不会显示结果不正确的三次方法在Scipy插值和没有阴影的线性方法?如果算法之间的选择是基于案例的,那么如何决定呢?如果能举例说明,会很有帮助。
import numpy as np
from matplotlib import cm
import matplotlib.pyplot as plt

plt.rcParams["figure.figsize"] = (19.2, 9.6)
save_dpi = 600

Azimuth = np.tile(np.arange(0, 91, 10), 10)
Deviation = np.repeat(np.arange(0, 91, 10), 10)
color_data = np.array([2123, 2124, 2126, 2130, 2135, 2139, 2144, 2147, 2150, 2151, 2212,
                       2211, 2205, 2197, 2187, 2176, 2166, 2158, 2152, 2150, 2478, 2468,
                       2439, 2395, 2342, 2285, 2231, 2188, 2160, 2150, 2912, 2888, 2819,
                       2715, 2589, 2456, 2334, 2236, 2172, 2150, 3493, 3449, 3324, 3135,
                       2908, 2674, 2462, 2294, 2187, 2150, 4020, 4020, 3912, 3618, 3270,
                       2917, 2602, 2357, 2203, 2151, 4020, 4020, 4020, 4020, 3633, 3156,
                       2737, 2417, 2218, 2150, 4020, 4020, 4020, 4020, 3947, 3358, 2850,
                       2466, 2230, 2150, 4020, 4020, 4020, 4020, 4020, 3495, 2926, 2499,
                       2238, 2150, 4020, 4020, 4020, 4020, 4020, 3543, 2951, 2510, 2241,
                       2150])

ax = plt.subplot(projection='polar')
plt.xticks([])
plt.yticks([])

Az = np.unique(Azimuth)
Dev = np.unique(Deviation)

mAz, mDev = np.meshgrid(Az, Dev)

# way1: Original
Xi, Yi, Zi = np.deg2rad(mAz), mDev, color_data.reshape(mAz.shape)
contour_plot = ax.contourf(Xi, Yi, Zi, levels=256, cmap=cm.viridis_r, zorder=1)
ax.plot()
plt.savefig("way1.png", dpi=save_dpi)

# way2: Interpolation
# import scipy.interpolate as sci_int
# Xi = np.linspace(0, 2 * np.pi, 256, endpoint=True)
# Yi = np.linspace(0, 90, 256, endpoint=True)
# Zi = sci_int.griddata(np.stack((np.deg2rad(mAz), mDev), axis=2).reshape(len(Azimuth), 2), color_data,
#                                                                             (Xi[None, :], Yi[:, None]), method='linear')
# contour_plot = ax.contourf(Xi, Yi, Zi, levels=256, cmap=cm.viridis_r, zorder=1)
# ax.plot()
# plt.savefig("way2.png", dpi=save_dpi)

字符串

在Windows 10上测试:
**Python版本:**3.8 & 3.10
**Matplotlib版本:**3.5.3和3.7.2

wh6knrhe

wh6knrhe1#

在一个相关的discussion in matplotlib repo之后,似乎没有任何简单和常规的解决方案(也许cartopy已经准备了一些有用的东西);* 轮廓绘制算法不知道它作用于极坐标图,因此当在极坐标空间中绘制轮廓时,多边形是近似的。
这实际上不是轮廓问题,而是一个坐标系中的直线是否应该转换为另一个坐标系中的直线或非直线的问题。它同样适用于任何多边形(例如仅仅是一个简单的三角形),例如以极坐标指定,并以笛卡尔(屏幕)坐标呈现。
只是为了子解决方案,我试图产生更多的点(Azimuth & Deviation)并插值其相应的 color_data(* 点越多,线条越短,看起来越接近圆形线段 *)以减少/弥补这个缺点。在这方面,对于本例,Radial basis function (RBF) interpolation of SciPy使用以下代码(可以针对此类问题进行开发/调整)获得可接受的答案:

from scipy.interpolate import RBFInterpolator

coordinates_org = np.column_stack((Azimuth, Deviation))
Az = np.linspace(0, 90, 181, endpoint=True)
Dev = np.linspace(0, 90, 181, endpoint=True)
Az_2D, Dev_2D = np.meshgrid(Az, Dev)
coordinates_int = np.column_stack((Az_2D.ravel(), Dev_2D.ravel()))
rbf = RBFInterpolator(coordinates_org, color_data, kernel="linear")
color_data_int = rbf(coordinates_int).reshape(len(Az), len(Dev))
contour_plot = ax.contourf(np.deg2rad(Az), Dev, color_data_int, levels=1000, cmap=cm.viridis_r)
ax.plot()
plt.savefig("way3.png", dpi=save_dpi)

字符串
x1c 0d1x的数据
我通过一些修改来调整另一个例子的解决方案,以将其结果与一些不同的插值方法进行比较,可以在下面看到。在这个比较中,griddata 圆圈上方的未填充区域可能会使用其他级别来填充,而不是使用其他级别,我记得是1000。基于比较,此解决方案(RBF)比在问题中使用 griddata 作为 way 2 产生更好的结果;另外,quintic 方法似乎是最好的:


相关问题