Plot Quiver Function - python

I am trying to create a quiver plot from a NetCDF file in Python using this code:
import matplotlib.pyplot as plt
import numpy as np
import netCDF4 as Dataset
ncfile = netCDF4.Dataset('30JUNE2012_0300UTC.cdf', 'r')
dbZ = ncfile.variables['MAXDBZF']
data = dbZ[0,0]
U = ncfile.variables['UNEW'][:]
V = ncfile.variables['VNEW'][:]
x, y= np.arange(0,2*np.pi,.2), np.arange(0,2*np.pi,.2)
X,Y = np.meshgrid(x,y)
plt.quiver(X,Y,U,V)
plt.show()
and I am getting the following errors
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-109-b449c540a7ea> in <module>()
11 X,Y = np.meshgrid(x,y)
12
---> 13 plt.quiver(X,Y,U,V)
14
15 plt.show()
/Users/felishalawrence/anaconda/lib/python2.7/site-packages/matplotlib/pyplot.pyc in quiver(*args, **kw)
3152 ax.hold(hold)
3153 try:
-> 3154 ret = ax.quiver(*args, **kw)
3155 draw_if_interactive()
3156 finally:
/Users/felishalawrence/anaconda/lib/python2.7/site-packages/matplotlib/axes/_axes.pyc in quiver(self, *args, **kw)
4162 if not self._hold:
4163 self.cla()
-> 4164 q = mquiver.Quiver(self, *args, **kw)
4165
4166 self.add_collection(q, autolim=True)
/Users/felishalawrence/anaconda/lib/python2.7/site-packages/matplotlib/quiver.pyc in __init__(self, ax, *args, **kw)
415 """
416 self.ax = ax
--> 417 X, Y, U, V, C = _parse_args(*args)
418 self.X = X
419 self.Y = Y
/Users/felishalawrence/anaconda/lib/python2.7/site-packages/matplotlib/quiver.pyc in _parse_args(*args)
377 nr, nc = 1, U.shape[0]
378 else:
--> 379 nr, nc = U.shape
380 if len(args) == 2: # remaining after removing U,V,C
381 X, Y = [np.array(a).ravel() for a in args]
ValueError: too many values to unpack
What does this error mean?

ValueError: too many values to unpack is because the line 379 of your program is trying to assign two variables (nr, nc) from U.shape when there are not enough variables to assign these values to.
Look above on line 377 - that is correctly assigning two values (1 and U.shape[0] to nr and nc but line 379 has only a U.shape object to assign to two variables. If there are more than 2 values in U.shape you will get this error. It was made clear that U.shape is actually a tuple with at least two values which means that this code would work as-is as long as there are an equal amount of values to assign to the variables (in this case two). I would print out the value of U.shape and determine that it holds the expected values and quantity of values. If you U.shape can return two or more values then your code will need to learn how to adapt to this. For example if you find that U.shape is a tuple of 3 values then you will need 3 variables to hold those values like so:
nr, nc, blah = U.shape
Consider the following:
a,b,c = ["a","b","c"] #works
print a
print b
print c
a, b = ["a","b","c"] #will result in error because 3 values are trying to be assigned to only 2 variables
The results from the above code:
a
b
c
Traceback (most recent call last):
File "None", line 7, in <module>
ValueError: too many values to unpack
So you see it's just a matter of having enough values to assign to all of the variables that are requesting a value.

Probably more useful to solve future problems rather then author's but still:
The problem was likely that the netcdf file had a time dimension, therefore U and V where 3 dimensional arrays - you should choose the time slice or aggregate the data across the time dimension.

Related

Getting error "unhashable type: 'numpy.ndarray' " while trying to plot vectors from two different .nc files

I have read two files using open_mfdataset. What I'm trying to do is create a vector plot for the wind stress data for which the i and j components are stored in two different files.
paths= [ "i stress.nc", "j stress.nc"]
DS=xr.open_mfdataset(paths)
DS
This is the data description
But while trying to do the vector plotting using quiver I'm getting this unhashable typeerror.
ax= plt.axes(projection=ccrs.PlateCarree())
U=DS.SOZOTAUX.mean(dim='TIME')
V=DS.SOMETAUY.mean(dim='TIME')
x="LON86_125"
y="LAT71_110"
X,Y=np.meshgrid(x,y)
plt.quiver(X,Y,U,V)
TypeError Traceback (most recent call last)
c:\Users\souga\OneDrive\Desktop\Python programs\Project.ipynb Cell 5 in <cell line: 8>()
5 y="LAT71_110"
6 X,Y=np.meshgrid(y,x)
----> 8 plt.quiver(X,Y,U,V)
File c:\Users\souga\anaconda3\lib\site-packages\matplotlib\pyplot.py:2788, in quiver(data, *args, **kwargs)
2786 #_copy_docstring_and_deprecators(Axes.quiver)
2787 def quiver(*args, data=None, **kwargs):
-> 2788 __ret = gca().quiver(
2789 *args, **({"data": data} if data is not None else {}),
2790 **kwargs)
2791 sci(__ret)
2792 return __ret
File c:\Users\souga\anaconda3\lib\site-packages\cartopy\mpl\geoaxes.py:310, in _add_transform.<locals>.wrapper(self, *args, **kwargs)
305 raise ValueError('Invalid transform: Spherical {} '
306 'is not supported - consider using '
307 'PlateCarree/RotatedPole.'.format(func.__name__))
309 kwargs['transform'] = transform
--> 310 return func(self, *args, **kwargs)
File c:\Users\souga\anaconda3\lib\site-packages\cartopy\mpl\geoaxes.py:1842, in GeoAxes.quiver(self, x, y, u, v, *args, **kwargs)
1840 x, y = np.meshgrid(x, y)
...
227 _api.check_isinstance((str, bytes), value=val)
228 if convertible:
229 # this will only be called so long as convertible is True.
TypeError: unhashable type: 'numpy.ndarray'
You're using matplotlib.pyplot.quiver, which expects arrays of numbers x, y, u, v. When you call the following:
x="LON86_125"
y="LAT71_110"
X,Y=np.meshgrid(x,y)
X and Y are 2D string arrays:
In [3]: X
Out[3]: array([['LON86_125']], dtype='<U9')
In [4]: Y
Out[4]: array([['LAT71_110']], dtype='<U9')
Instead, I think you're looking for something along the lines of
X, Y = np.meshgrid(DS['LON86_125'].values, DS['LAT71_110'].values)
That said, you might try xarray.Dataset.plot.quiver which can work directly with xarray objects, and does accept string arguments referring to the dataset's variable and coordinate names:
DS.mean(dim='TIME').plot.quiver(
x='LON86_125',
y='LAT71_110',
u='SOZOTAUX',
v='SOMETAUY',
)

Dask looping over library function call

Goal
I would like to parallelize a loop with dask that uses a library function inside the loop. This function, mhw.detect(), calculates some statistics on a slice of a numpy array. None of the slices of the array depend on the other slices, so I was hoping that dask could be used to compute them in parallel and store them all in the same output array.
Code
The flow of the code I am working on is:
import numpy as np
import marineHeatWaves as mhw
from dask import delayed
# Create fake input data
lat_size, long_size = 100, 100
data = np.random.random_integers(0, 30, size=(10_000, long_size, lat_size)) # size = (time, longitude, latitude)
time = np.arange(730_000, 740_000) # time in ordinal days
# Initialize an empty array to hold the output
output_array = np.empty(data.shape)
# loop through each pixel in the data array
for idx_lat in range(lat_size):
for idx_long in range(long_size):
# Extract a slice of data
data_slice = data[:, idx_lat, idx_long]
# Use the library function to calculate the stats for the pixel
# `library_output` is a dictionary that has a numpy array inside it
_, library_output = delayed(mhw.detect)(time, data_slice)
# Update the output array with the calculated values from the library
output_array[:, idx_lat, idx_long] = library_output['seas']
Previous efforts
When I run this code I get the error TypeError: Delayed objects of unspecified length are not iterable. Another stack overflow post discusses this issue and resolves the issue by converting the output of the delayed function to a delayed object. However, because I didn't create the output object myself I am not sure if I can convert it to a delayed object.
I've also tried wrapping the last line in da.from_delayed(), as in output_array[:, idx_lat, idx_long] = da.from_delayed(library_output['seas']) and initalizing the output_array with da.empty(data.shape). I get the same error, though, since I think the code doesn't make it past the line with the library function delayed(mhw.detect)(time, data_slice).
Is it possible to parallelize this? Is this approach of asking dask to compute all the slices in parallel and put them together in an output array even a reasonable approach?
Full Traceback
TypeError Traceback (most recent call last)
/home/rwegener/mhw-ocetrac-census/notebooks/ejoliver_subset_MUR.ipynb Cell 44' in <cell line: 10>()
13 data_slice = data[:, idx_lat, idx_long]
14 # Use the library function to calculate the stats for the pixel
---> 15 _, point_clim = delayed(mhw.detect)(time_ordinal, data_slice)
16 # Update the output array with the calculated values from the library
17 output_array[:, idx_lat, idx_long] = point_clim['seas']
File ~/.conda/envs/dask/lib/python3.10/site-packages/dask/delayed.py:581, in Delayed.__iter__(self)
579 def __iter__(self):
580 if self._length is None:
--> 581 raise TypeError("Delayed objects of unspecified length are not iterable")
582 for i in range(self._length):
583 yield self[i]
TypeError: Delayed objects of unspecified length are not iterable
Update
Using .apply_along_axis() as suggested:
# Create fake input data
lat_size, long_size = 100, 100
data = np.random.randint(0, 30, size=(10_000, long_size, lat_size)) # size = (time, longitude, latitude)
data = dask.array.from_array(data, chunks=(-1, 100, 100))
time = np.arange(730_000, 740_000) # time in ordinal days
# Initialize an empty array to hold the output
output_array = np.empty(data.shape)
# define a wrapper to rearrange arguments
def func1d(arr, time, shape=(10000,)):
print(arr.shape)
return mhw.detect(time, arr)
res = dask.array.apply_along_axis(func1d, 0, data, time=time)
With the output:
(1,)
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
/homes/metogra/rwegener/mhw-ocetrac-census/notebooks/ejoliver_subset_MUR.ipynb Cell 48' in <cell line: 15>()
12 print(arr.shape)
13 return mhw.detect(time, arr)
---> 15 res = dask.array.apply_along_axis(func1d, 0, data, time=time)
File ~/.conda/envs/dask/lib/python3.10/site-packages/dask/array/routines.py:508, in apply_along_axis(func1d, axis, arr, dtype, shape, *args, **kwargs)
506 if shape is None or dtype is None:
507 test_data = np.ones((1,), dtype=arr.dtype)
--> 508 test_result = np.array(func1d(test_data, *args, **kwargs))
509 if shape is None:
510 shape = test_result.shape
/homes/metogra/rwegener/mhw-ocetrac-census/notebooks/ejoliver_subset_MUR.ipynb Cell 48' in func1d(arr, time, shape)
11 def func1d(arr, time, shape=(10000,)):
12 print(arr.shape)
---> 13 return mhw.detect(time, arr)
File ~/.conda/envs/dask/lib/python3.10/site-packages/marineHeatWaves-0.28-py3.10.egg/marineHeatWaves.py:280, in detect(t, temp, climatologyPeriod, pctile, windowHalfWidth, smoothPercentile, smoothPercentileWidth, minDuration, joinAcrossGaps, maxGap, maxPadLength, coldSpells, alternateClimatology, Ly)
278 tt = tt[tt>=0] # Reject indices "before" the first element
279 tt = tt[tt<TClim] # Reject indices "after" the last element
--> 280 thresh_climYear[d-1] = np.nanpercentile(tempClim[tt.astype(int)], pctile)
281 seas_climYear[d-1] = np.nanmean(tempClim[tt.astype(int)])
282 # Special case for Feb 29
IndexError: index 115 is out of bounds for axis 0 with size 1
Rather than using delayed, this seems like a good case for dask.array.
You can create the dask array by partitioning the numpy array:
da = dask.array.from_array(output_array, chunks=(-1, 10, 10))
Now you can call mhw.detect using dask.array.map_blocks alongside np.apply_along_axis within each block:
# define a wrapper to rearrange arguments
def func1d(arr, time):
return mhw.detect(time, arr)
def block_func(block, **kwargs):
return np.apply_along_axis(func1d, 0, block, **kwargs)
res = data.map_blocks(block_func, meta=data, time=time)
res = res.compute()
The map_blocks answer above works great! Additionally, apply_along_axis() was suggested and discussed in comments. I was able to get that method to work, but in order for it to function properly you need to use both the dtype and shape inputs to da.apply_along_axis(). If these aren't supplied the function can't figure out the shape of the data it should pass as an argument.
So, another solution:
import dask.array as da
# Create fake input data
lat_size, long_size = 100, 100
data = da.random.random_integers(0, 30, size=(1_000, long_size, lat_size), chunks=(-1, 10, 10)) # size = (time, longitude, latitude)
time = np.arange(730_000, 731_000) # time in ordinal days
# define a wrapper to rearrange arguments
def func1d(arr, time):
return mhw.detect(time, arr)
result = da.apply_along_axis(func1d, 0, data, time=time, dtype=data.dtype, shape=(1000,))
result.compute()

3D graph error: "The truth value of an array with more than one element is ambiguous"

I am trying to plot a 3D graph, using a re-existing function to generate the Z values. However, this is yielding the error "The truth value of an array with more than one element is ambiguous". This seems strange, as I am able to generate a list of Z values using the same function and y,x values, but once I include the 3D graphing code the error occurs.
My graphing code is:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
from matplotlib import cm
def f(tau,tau_b): #re-use society welfare function of tau & tau_b, using corr=0.6
Z = society_welfare2 (0.6, tau, tau_b)
return Z
xgrid=np.linspace(1e-5, 1-1e-5,100) #tau grid
ygrid=np.linspace(1e-5, 1-1e-5,100) #tau_b grid
tau,tau_b=np.meshgrid(xgrid,ygrid)
fig=plt.figure(figsize=(8,6))
ax=fig.add_subplot(111,projection='3d')
ax.plot_surface(tau,
tau_b,
f(tau,tau_b),
rstride=2,cstride=2,
cmap=cm.jet,
alpha=0.7,
linewidth=0.25)
ax.set_zlim(-0.5,1.0)
plt.show()
My society_welfare2 function code:
def society_welfare2 (corr, tau, tau_b):
cov = [[1,corr], [corr,1]] #covariance
epsilon_start,b_start = np.random.multivariate_normal(mean, cov, sample_N).T
epsilon = np.exp(epsilon_start) #to ensure epsilon positive
b = np.exp(b_start) #to ensure b positive
indv_welfares = []
def GBC (t_o):
taxes_paid = []
for i in range(sample_N): #loop over all agents to find their C1,C2,L
def consumption_functions(Lguess,epsilon=epsilon,b=b):
C2 = (((1-tau)*epsilon[i]*w*Lguess) +(1-tau_b)*b[i] + ((t_o)/(1+r)))/((1/((beta**(1/gamma))*((1+r)**(1/gamma)))) + (1/(1+r)))
C1 = C2 /((beta**(1/gamma))*(1+r)**(1/gamma))
return -Utility(C1,C2,Lguess)
result = minimize_scalar(consumption_functions,bounds=(0,1),method='bounded', args=(epsilon, b))
opt_L = result.x
opt_C1=(((1-tau)*(epsilon[i])*w)/(opt_L**sigma))**(1/gamma)
opt_C2=(opt_C1)*((beta**(1/gamma))*(1+r)**(1/gamma))
income_tax = tau*(epsilon[i])*w*opt_L
bequest_tax = tau_b*(b[i])
taxes_paid.append(income_tax)
taxes_paid.append(bequest_tax)
welfare_func = opt_C1**(1-gamma)/(1-gamma)-opt_L**(1+sigma)/(1+sigma) + beta*(opt_C2**(1-gamma)/(1-gamma))
indv_welfares.append(welfare_func)
total_tax_revenue = sum(taxes_paid)
return total_tax_revenue - (10000*t_o)
result1 = minimize_scalar(GBC,bounds=(1e-5, 100000),method='bounded')
opt_t_o = result1.x
total_welfare = sum(indv_welfares)
return total_welfare
The full traceback error code:
ValueError Traceback (most recent call last)
<ipython-input-19-3633f4a9db76> in <module>
18 ax.plot_surface(tau,
19 tau_b,
---> 20 f(tau,tau_b),
21 rstride=2,cstride=2,
22 cmap=cm.jet,
<ipython-input-19-3633f4a9db76> in f(tau, tau_b)
7
8 def f(tau,tau_b): #re-use society welfare function of tau & tau_b, using corr=0.6
----> 9 Z = society_welfare2 (0.6, tau, tau_b)
10 return Z
11
<ipython-input-17-321a709b9684> in society_welfare2(corr, tau, tau_b)
61 return total_tax_revenue - (10000*t_o)
62
---> 63 result1 = minimize_scalar(GBC,bounds=(1e-5, 100000),method='bounded')
64
65 opt_t_o = result1.x
/opt/anaconda3/lib/python3.8/site-packages/scipy/optimize/_minimize.py in minimize_scalar(fun, bracket, bounds, args, method, tol, options)
798 if isinstance(disp, bool):
799 options['disp'] = 2 * int(disp)
--> 800 return _minimize_scalar_bounded(fun, bounds, args, **options)
801 elif meth == 'golden':
802 return _minimize_scalar_golden(fun, bracket, args, **options)
/opt/anaconda3/lib/python3.8/site-packages/scipy/optimize/optimize.py in _minimize_scalar_bounded(func, bounds, args, xatol, maxiter, disp, **unknown_options)
1956 rat = e = 0.0
1957 x = xf
-> 1958 fx = func(x, *args)
1959 num = 1
1960 fmin_data = (1, xf, fx)
<ipython-input-17-321a709b9684> in GBC(t_o)
41 return -Utility(C1,C2,Lguess)
42
---> 43 result = minimize_scalar(consumption_functions,bounds=(0,1),method='bounded', args=(epsilon, b))
44
45 opt_L = result.x
/opt/anaconda3/lib/python3.8/site-packages/scipy/optimize/_minimize.py in minimize_scalar(fun, bracket, bounds, args, method, tol, options)
798 if isinstance(disp, bool):
799 options['disp'] = 2 * int(disp)
--> 800 return _minimize_scalar_bounded(fun, bounds, args, **options)
801 elif meth == 'golden':
802 return _minimize_scalar_golden(fun, bracket, args, **options)
/opt/anaconda3/lib/python3.8/site-packages/scipy/optimize/optimize.py in _minimize_scalar_bounded(func, bounds, args, xatol, maxiter, disp, **unknown_options)
2015 print("%5.0f %12.6g %12.6g %s" % (fmin_data + (step,)))
2016
-> 2017 if fu <= fx:
2018 if x >= xf:
2019 a = xf
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
The lowest point the trace back is
if fu <= fx:
That's comparing two variables in an if. That will work if fu and fx are scalars, or single value arrays. But if either is a multivalue array if will raise this error.
Our task at this point is to trace those variables back to your code. I suspect you are providing arrays for some parameter, where they/is should be a scalar.
Looking at the top. It occurs when you ask for the plot, but a parameter is a function call:
f(tau,tau_b)
and on through a function calls to the minimize on the GBC function. I think that GBC is the func in:
fx = func(x, *args)
Which raises the question, what exactly does GBC return? It's being used in a _minimize_scalar, so it should return exactly one value.
What is its return expression?
return total_tax_revenue - (10000*t_o)
Do you think you can take the analysis from there?
Now do you see why we insist on seeing the traceback. The error is in your code, but the sequence getting there is long, and not obvious from simply reading the code.
edit
Oops, I see another level of minimize, one that uses
consumption_functions
It has several parameters, epsilon and b. I suppose we can deduce what those are. But what is
Utility
The fu <= fx appears to be testing the fx return value against a bound fu. Assuming the bound is scalar, then the value fx must be an array. Is it???

Index Error: Index 206893 is out of bounds for axis 0 with size 206893, griddata issue

I have an issue for the last 4 days trying to understand a python error:
`enter code here`IndexError: index 206893 is out of bounds for axis 0 with size 206893
when applying, griddata and "nearest" interpolation method using the following lines:
create a matrix where I will store the first interpolated file
tempnew = np.ones((np.asarray(w1[0,0,:,:]).shape))*np.nan
The lon, lat coordinate points of the original grid
lonl,latl = np.meshgrid(lon,lat)
points = np.vstack((np.array(lonl).flatten(),np.array(latl).flatten())).transpose()
The values of the original file
values = np.array([np.asarray(temp[0,0,:,:])]).flatten()
The dimensions of the grid that I want to interpolate to
lons = np.array(nav_lon)
lats = np.array(nav_lat)
X,Y = np.meshgrid(lons,lats)
Interpolation
tempnew = griddata(points,values, (X,Y), method = "nearest",fill_value=-3)
Here the dimension of each of the variables that I use above:
#tempnew.shape: (728, 312) #(Dimensions of tempnew is (lats,lons))
#lat.shape: (661,) #(original latitude)
#lon.shape: (313,) #(original longitude)
#points.shape: (206893, 2)
#values.shape: (206893,)
#X.shape: (728, 312)
#Y.shape: (728, 312)
Can you help me? * I would like to note here that the original file grid is regular (A-type) grid data whereas the grid to which I want to interpolate to is not regular (C-grid data)
The error looks like this:
In [36]: tempnew = sp.interpolate.griddata(points,values, (X,Y), method = "nearest
...: ",fill_value=-3)
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-36-0d0b46a3542f> in <module>
----> 1 tempnew = sp.interpolate.griddata(points,values, (X,Y), method =
"nearest",fill_value=-3)
~/software/anaconda3/envs/mhw/lib/python3.7/site-packages/scipy/interpolate/ndgriddata.py in
griddata(points, values, xi, method, fill_value, rescale)
217 elif method == 'nearest':
218 ip = NearestNDInterpolator(points, values, rescale=rescale)
--> 219 return ip(xi)
220 elif method == 'linear':
221 ip = LinearNDInterpolator(points, values, fill_value=fill_value,
~/software/anaconda3/envs/mhw/lib/python3.7/site-packages/scipy/interpolate/ndgriddata.py in
__call__(self, *args)
79 xi = self._scale_x(xi)
80 dist, i = self.tree.query(xi)
---> 81 return self.values[i]
82
83
IndexError: index 206893 is out of bounds for axis 0 with size 206893
Thanks in advance,
Sofi
I encountered this error in my Python code using the scipy.interpolate.NearestNDInterpolator class. The error message that is returned is not very clear. In the end, I found that one of the values I was inserting into my interpolant had a value of 1e184 and caused this error message. After resetting this value to 0.0, my Python script ran successfully.

Python numpy: create 2d array of values based on coordinates and plot with pcolormesh, heatplolt

I have arrays with Latitude (Lat) and an Lonitude, which is both a 1D array with the shape of 5.
Then I have another array with the value C, this is also a 1D array, with the shape of 5. I would like to plot the hole thing with pcolormesh at the end, so a kind of heatmap plot!
Here is the corresponding code:
import numpy as np
import matplotlib.pyplot as plt
In [13]:
# Data
Lat = np.array([-65.62282562, -65.62266541, -65.62241364, -65.62398529, -65.62410736])
Lon = np.array([145.28251648, 145.38883972, 145.49528503, 121.4509201, 121.55738068, 121.66372681])
C = np.array([0., 0.5, 2, 3, 0])
# Plot
plt.pcolormesh(X, Y, C)
Then I get the following error
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-14-164126d430da> in <module>()
1 # Plot
----> 2 plt.pcolormesh(X, Y, C)
/home/unix/anaconda2/lib/python2.7/site-packages/matplotlib/pyplot.pyc in pcolormesh(*args, **kwargs)
3091 ax.hold(hold)
3092 try:
-> 3093 ret = ax.pcolormesh(*args, **kwargs)
3094 finally:
3095 ax.hold(washold)
/home/unix/anaconda2/lib/python2.7/site-packages/matplotlib/__init__.pyc in inner(ax, *args, **kwargs)
1810 warnings.warn(msg % (label_namer, func.__name__),
1811 RuntimeWarning, stacklevel=2)
-> 1812 return func(ax, *args, **kwargs)
1813 pre_doc = inner.__doc__
1814 if pre_doc is None:
/home/unix/anaconda2/lib/python2.7/site-packages/matplotlib/axes/_axes.pyc in pcolormesh(self, *args, **kwargs)
5393 allmatch = (shading == 'gouraud')
5394
-> 5395 X, Y, C = self._pcolorargs('pcolormesh', *args, allmatch=allmatch)
5396 Ny, Nx = X.shape
5397
/home/unix/anaconda2/lib/python2.7/site-packages/matplotlib/axes/_axes.pyc in _pcolorargs(funcname, *args, **kw)
4993 if len(args) == 3:
4994 X, Y, C = [np.asanyarray(a) for a in args]
-> 4995 numRows, numCols = C.shape
4996 else:
4997 raise TypeError(
ValueError: need more than 1 value to unpack
So would like to give each X-Y-pair one C value, so there are 5 XY pairs, and 5 C values. In theory it should be no problem, but I really can not find a solution!
You have two problems, one logical and one when you call pcolormesh:
The first is that C and Lat contain 5 values but Lon contains 6 values. That means you don't have 5 XY values and 5 C values, so that's something you should work out.
But it's possible to create a pcolormesh with several distinct coordinates if you expand your coordinates correctly:
import numpy as np
import matplotlib.pyplot as plt
plt.figure()
# Data
Lat = np.array([-65.62282562, -65.62266541, -65.62241364, -65.62398529, -65.62410736])
Lon = np.array([145.28251648, 145.38883972, 145.49528503, 121.4509201, 121.55738068])
C = np.array([0., 0.5, 2, 3, 0])
# Plot
plt.pcolormesh(np.expand_dims(Lat, 0), np.expand_dims(Lon, 1), C*np.eye(5))
The expand_dims will make the dimensions correctly broadcast against each other and the np.eye makes sure that the correct values will have the values you assigned in C and all other coordinates will be zero.
But the output probably won't look good because that's a really sparse coordinate frame.
There are other alternative to pcolormesh, especially weighted histograms could be of interest or contours:
Lat = np.random.normal(-65, 2, 50000)
Lon = np.random.normal(130, 5, 50000)
C = np.random.randint(0, 10, 50000)
plt.figure()
plt.hexbin(Lat, Lon, C=C, cmap=plt.cm.hot)
pcolormesh is for plotting meshes. Meshes are grids of values (for all three of lat, lon, and C), and pcolormesh will plot lines and quads connecting adjacent values within the grid.
You don't have a mesh (2d), you have at best a polyline (1d). That doesn't contain enough information for a unique heat map.
Pcolormesh is intended to be used with 2D variables. If you use np.eye for a variable having large amount of data (as in your real case), you might run into memory problems.
One can use scatter in the following way to get an outcome like pcolormesh with 1D array which has the same shape as that of two arrays and its values are present at each pair of values of the two arrays.
import numpy as np
import matplotlib.pyplot as plt
# Data
Lat = np.array([-65.62282562, -65.62266541, -65.62241364, -65.62398529, -65.62410736])
Lon = np.array([145.28251648, 145.38883972, 145.49528503, 121.4509201, 121.55738068])
X=np.array(Lat[:]).tolist()
Y=np.array(Lon[:]).tolist()
C = np.array([0., 0.5, 2, 3, 0])
C = np.array(C[:]).tolist()
# Plot
plt.scatter(X, Y, c=C, s=10)

Categories

Resources