I have tried to create a polar plot using matplotlib's contourf
, but it produces some not-filled areas near the circle boundary, in just some sides of the plot. It seems, this problem is a common problem that we can see in many examples e.g. 1.
At first, I thought it may needs some interpolations and tried interpolating based on some available methods e.g. 2. But I couldn't produce a perfect plot. Interpolating using SciPy griddata with linear method solved the main issue but produce some shadows on the plot, and the cubic method result in some inappropriate colors (which shown the results incorrect).
Finally, I guess this issue may be related to figure size that I specified and the dpi that I used. With low dpi it was cured a lot, but will get a low quality png. when I deactivate the related line for specifying figure size (# plt.rcParams["figure.figsize"] = (19.2, 9.6)
) with dpi=600
, it is shown fairly correct, but not on the needed figure size.
The main question is how to solve the issue for saved files, with the desired specified figure size and dpi? It must be said that the problem is appearing on the saved files.
Besides the answer to solve the issue, I will be appreciated if any answer about these questions too:
Why it happens?
Why it happens just in some sides of the plot? In this example it is problematic just on the right side of the quarter, not the upside. This issue makes me doubt that the data is correctly shown on the circle for analysis. Is it OK?
Do we need interpolating on such data? If so, which algorithms will be the best for that which does not show the results incorrectly as cubic method in Scipy interpolation and without shadowing as the linear method? If choosing between algorithms is based on the case, how to decide for that? It will be very helpful if be explained with examples.
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)
Tested on windows 10 by:
Python ver.: 3.8 & 3.10
Matplotlib ver.: 3.5.3 & 3.7.2