简体   繁体   English

使用matplotlib散点图绘制负值

[英]Plotting negative values using matplotlib scatter

I want to plot scatter points corresponding to 6 different datasets over global maps of the Earth. 我想在地球的全球地图上绘制与6个不同数据集相对应的散点。 The problem is that some of these quantities have negative values and they don't appear in the maps. 问题在于这些数量中的一些具有负值,并且它们不会出现在地图中。 I have tried to overcome this problem by taking absolute values of the data and multiplying (or taking the power of) them by some factors, but nothing seems to work the way I want. 我试图通过采用数据的绝对值并将其乘以(或采用其功效)某些因素来克服此问题,但是似乎没有任何方法可以按照我想要的方式工作。 The problem is that the datasets have very different ranges. 问题在于数据集的范围非常不同。 Ideally, I want them all to have the same scale so everything will be more organized, but I don't know how to do this. 理想情况下,我希望它们所有人都具有相同的规模,以便使所有事情都井井有条,但是我不知道该怎么做。

I created some synthetic data to illustrate this issue 我创建了一些综合数据来说明此问题

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')

在此处输入图片说明

As you can see in the map, negative data does not are not being exhibited. 正如您在地图上看到的那样,没有显示负面数据。 I want they all to appear in the maps and that all the scatter plots have the same scale in their respective ranges. 我希望它们全部出现在地图中,并且所有散点图在各自的范围内具有相同的比例。 Thanks! 谢谢!

It looks like you are trying to map your dataset to dot size. 似乎您正在尝试将数据集映射到点大小。 Obviously you cannot have negative size dots, so that won't work. 显然,您不能使用负尺寸的点,因此无法使用。

Instead, you need to normalize your dataset to a strictly positive range and use those normalized values for the size parameter. 相反,您需要将数据集规范化为严格的正范围,并使用这些规范化的值作为size参数。 A simple way to do this would be to use matplotlib.colors.Normalize(vmin, vmax) , which allows you to map any values in the interval [vmin, vmax] to the interval [0,1]. 一种简单的方法是使用matplotlib.colors.Normalize(vmin, vmax) ,它允许您将间隔[vmin,vmax]中的任何值映射到间隔[0,1]。

If you want to have a shared scale for all your datasets, first find the global min and max, and use that to instantiate your normalization, then normalize each dataset when plotting: 如果要为所有数据集共享比例,请首先找到全局最小值和最大值,然后使用它来实例化归一化,然后在绘制时对每个数据集进行归一化:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM