我想创建一个具有平滑颜色的 2D 合并“颜色图”版本。
我什至不确定这是否是该图的正确命名法,但从本质上讲,我希望我的图形由驻留在我的 (X) 的每个定义箱中的点的第三个变量的中值进行颜色编码, Y)空间。
尽管我能够在一定程度上实现这一点(参见示例),但我想找到一种方法来创建具有平滑颜色渐变的同一图的版本。这将使我能够可视化分布的整体行为。
我尝试了这里描述的想法:Smoothing 2D map in python
这里:Python: binned_statistic_2d mean calculation ignoring NaNs in data
以及其中的链接,但找不到问题的明确解决方案。
这是我目前所拥有的:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from scipy.stats import binned_statistic_2d
import random
random.seed(999)
x = np.random.normal (0,10,5000)
y = np.random.normal (0,10,5000)
z = np.random.uniform(0,10,5000)
fig = plt.figure(figsize=(20, 20))
plt.rcParams.update({'font.size': 10})
ax = fig.add_subplot(3,3,1)
ax.set_axisbelow(True)
plt.grid(b=True, lw=0.5, zorder=-1)
x_bins = np.arange(-50., 50.5, 1.)
y_bins = np.arange(-50., 50.5, 1.)
cmap = plt.cm.get_cmap('jet_r',1000) #just a colormap
ret = binned_statistic_2d(x, y, z, statistic=np.median, bins=[x_bins, y_bins]) # Bin (X, Y) and create a map of the medians of "Colors"
plt.imshow(ret.statistic.T, origin='bottom', extent=(-50, 50, -50, 50), cmap=cmap)
plt.xlim(-40,40)
plt.ylim(-40,40)
plt.xlabel("X", fontsize=15)
plt.ylabel("Y", fontsize=15)
ax.set_yticks([-40,-30,-20,-10,0,10,20,30,40])
bounds = np.arange(2.0, 20.0, 1.0)
plt.colorbar(ticks=bounds, label="Color", fraction=0.046, pad=0.04)
# save plots
plt.savefig("Whatever_name.png", bbox_inches='tight')
生成以下图像(来自随机数据):
因此,简单的问题是:如何平滑这些颜色?
提前致谢!
PS:抱歉编码过多,但我相信清晰的可视化对于这个特定问题至关重要。
最佳答案
感谢所有查看此问题并试图提供帮助的人!
我最终能够解决自己的问题。最后,一切都是关于使用高斯核进行图像平滑。
此链接:Gaussian filtering a image with Nan in Python给了我解决方案的洞察力。
基本上,我实现了完全相同的代码,但最后,将先前已知的 NaN 像素从原始二维数组映射到生成的平滑版本。与链接中的解决方案不同,我的版本不会使用从周围像素派生的某些值填充 NaN 像素。或者,确实如此,但我又将它们擦掉了。
这是为我提供的示例生成的最终图形:
最终代码,供以后可能需要的 friend 引用:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from scipy.stats import binned_statistic_2d
import scipy.stats as st
import scipy.ndimage
import scipy as sp
import random
random.seed(999)
x = np.random.normal (0,10,5000)
y = np.random.normal (0,10,5000)
z = np.random.uniform(0,10,5000)
fig = plt.figure(figsize=(20, 20))
plt.rcParams.update({'font.size': 10})
ax = fig.add_subplot(3,3,1)
ax.set_axisbelow(True)
plt.grid(b=True, lw=0.5, zorder=-1)
x_bins = np.arange(-50., 50.5, 1.)
y_bins = np.arange(-50., 50.5, 1.)
cmap = plt.cm.get_cmap('jet_r',1000) #just a colormap
ret = binned_statistic_2d(x, y, z, statistic=np.median, bins=[x_bins, y_bins]) # Bin (X, Y) and create a map of the medians of "Colors"
sigma=1 # standard deviation for Gaussian kernel
truncate=5.0 # truncate filter at this many sigmas
U = ret.statistic.T.copy()
V=U.copy()
V[np.isnan(U)]=0
VV=sp.ndimage.gaussian_filter(V,sigma=sigma)
W=0*U.copy()+1
W[np.isnan(U)]=0
WW=sp.ndimage.gaussian_filter(W,sigma=sigma)
np.seterr(divide='ignore', invalid='ignore')
Z=VV/WW
for i in range(len(Z)):
for j in range(len(Z[0])):
if np.isnan(U[i][j]):
Z[i][j] = np.nan
plt.imshow(Z, origin='bottom', extent=(-50, 50, -50, 50), cmap=cmap)
plt.xlim(-40,40)
plt.ylim(-40,40)
plt.xlabel("X", fontsize=15)
plt.ylabel("Y", fontsize=15)
ax.set_yticks([-40,-30,-20,-10,0,10,20,30,40])
bounds = np.arange(2.0, 20.0, 1.0)
plt.colorbar(ticks=bounds, label="Color", fraction=0.046, pad=0.04)
# save plots
plt.savefig("Whatever_name.png", bbox_inches='tight')
关于python-3.x - python : how to create a smoothed version of a 2D binned "color map"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63817766/