python - 使用 matplotlib scatter 绘制负值
问题描述
我想在地球的全球地图上绘制对应于 6 个不同数据集的散点。问题是其中一些量具有负值并且它们没有出现在地图中。我试图通过获取数据的绝对值并将它们乘以(或乘以)某些因素来克服这个问题,但似乎没有什么能按我想要的方式工作。问题是数据集的范围非常不同。理想情况下,我希望它们都具有相同的规模,这样一切都会更有条理,但我不知道如何做到这一点。
我创建了一些合成数据来说明这个问题
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.basemap import Basemap, addcyclic, shiftgrid
from matplotlib.pyplot import cm
np.random.seed(100)
VarReTx = np.random.uniform(low=-0.087, high=0.0798, size=(52,))
VarReTy = np.random.uniform(low=-0.076, high=0.1919, size=(52,))
VarImTx = np.random.uniform(low=-0.0331, high=0.0527, size=(52,))
VarImTy = np.random.uniform(low=-0.0311, high=0.2007, size=(52,))
eTx = np.random.uniform(low=0.0019, high=0.0612, size=(52,))
eTx = np.random.uniform(low=0.0031, high=0.0258, size=(52,))
obslat = np.array([18.62, -65.25, -13.8, -7.95, -23.77, 51.84, 40.14, 58.07,
-12.1875, -35.32, 36.37, -46.43, 40.957, -43.474, 38.2 , 37.09,
48.17, 0.6946, 13.59, 28.32, 51., -25.88, -34.43, 21.32,
-12.05, 52.27, 36.23, -12.69, 31.42, 5.21, -22.22, 36.1,
14.38, -54.5, 43.91, 61.16, 48.27, 52.07, 54.85, 45.403,
52.971, -17.57, -51.7, 18.11, 39.55, 47.595, 22.79, -37.067,
-1.2, 32.18, 51.933, 48.52])
obslong = np.array([-287.13, -64.25, -171.78, -14.38, -226.12, -339.21, -105.24,
-321.77, -263.1664, -210.64, -233.146, -308.13, -359.667, -187.607,
-77.37, -119.72, -348.72, -287.8463, -215.13, -16.43, -4.48,
-332.29, -340.77, -158., -75.33, -255.55, -219.82, -227.53,
-229.12, -52.73, -245.9, -256.16, -16.97, -201.05, -215.81,
-45.442, -117.12, -347.32, -276.77, -75.552, -201.752, -149.58,
-57.89, -66.15, -4.35, -52.677, -354.47, -12.315, -48.5,
-110.73, -10.25, -123.42, ])
fig, ([ax1, ax2], [ax3, ax4], [eax1, eax2]) = plt.subplots(3,2, figsize=(24,23))
matplotlib.rc('xtick', labelsize=12)
matplotlib.rc('ytick', labelsize=12)
plots = [ax1, ax2, ax3, ax4, eax1, eax2]
Vars = [VarReTx, VarReTy, VarImTx, VarImTy, eTx, eTy]
titles = [r'$\Delta$ ReTx', r'$\Delta$ ReTy', r'$\Delta$ ImTx', r'$\Delta$ ImTy', 'Error (X)', 'Error (Y)']
colors = iter(cm.jet(np.reshape(np.linspace(0.0, 1.0, len(plots)), ((len(plots), 1)))))
for j in range(len(plots)):
c3 = next(colors)
lat = np.arange(-91, 91, 0.5)
long = np.arange(-0.1, 360.1, 0.5)
longrid, latgrid = np.meshgrid(long, lat)
plots[j].set_title(titles[j], fontsize=48, y=1.05)
condmap = Basemap(projection='robin', llcrnrlat=-90, urcrnrlat=90,\
llcrnrlon=-180, urcrnrlon=180, resolution='c', lon_0=0, ax=plots[j])
maplong, maplat = condmap(longrid, latgrid)
condmap.drawcoastlines()
condmap.drawmapboundary(fill_color='white')
parallels = np.arange(-90, 90, 15)
condmap.drawparallels(parallels,labels=[False,True,True,False], fontsize=15)
x,y = condmap(obslong, obslat)
w = []
for m in range(obslong.size):
w.append(Vars[j][m])
w = np.array(w)
condmap.scatter(x, y, s = w*1e+4, c=c3)
r = np.linspace(np.min(Vars[j]), np.max(Vars[j]), 4)
for n in r:
condmap.scatter([], [], c=c3, s=n*1e+4, label=str(np.round(n, 4)))
plots[j].legend(bbox_to_anchor=(0., -0.2, 1., .102), loc='lower left',
ncol=4, mode="expand", borderaxespad=0., fontsize=16, frameon = False)
plt.show()
plt.close('all')
正如您在地图中看到的那样,负面数据并没有被展示出来。我希望它们都出现在地图中,并且所有散点图在各自的范围内都具有相同的比例。谢谢!
解决方案
看起来您正在尝试将数据集映射到点大小。显然你不能有负大小的点,所以那是行不通的。
相反,您需要将数据集标准化为严格的正范围,并将这些标准化值用于 size 参数。一个简单的方法是使用matplotlib.colors.Normalize(vmin, vmax)
,它允许您将区间 [vmin, vmax] 中的任何值映射到区间 [0,1]。
如果您想为所有数据集共享比例,首先找到全局最小值和最大值,并使用它来实例化您的规范化,然后在绘图时规范化每个数据集:
datasets = [VarReTx,VarReTy,VarImTx,VarImTy,eTx,eTx]
min_val = min([d.min() for d in datasets])
max_val = max([d.max() for d in datasets])
norm = matplotlib.colors.Normalize(vmin=min_val, vmax=max_val)
plt.scatter(x,y,s=norm(VarReTx)*100) # choose appropiate scaling factor instead of 100 to get nicely sized dots
推荐阅读
- php - 如何修复“未捕获的 InvalidArgumentException:找不到操作:CreateCollection”
- selenium - Selenium::Remote::Driver - 过时的元素引用:元素未附加到页面文档
- apache-spark - PySpark 从多列中选择前 N 个
- javascript - 量角器无法识别功能
- highcharts - 图表上的 HighCharts 发光效果不影响多个图表
- python - nyoka AttributeError:该层从未被调用,因此没有定义的输入形状
- java - 通过 Linux 执行 Java 时面临的问题:无法找到或加载主类
- c++ - 派生类可以从给定派生类模板化的模板化基类继承吗?这是个好主意吗?
- python - Postgresql python插入,列关系不存在
- javascript - 如何连接字符串和输入值以用于 xero api 的 JSON