python - White area on matplotlib plot with pygrib data between 359.5 and 360 degrees -
what try plot output of gfs weather model matplotlib using pygrib save data, saved in grib files. works fine, output looks this:
it appears program isn't closing gap between 359.5 , 360 degress using data of 0 degress. if data in regular list or use data of 0° , save 360° appending list. i've seen people having same problem non-pygrib data. if know how change pygrib data (regular operations don't work on pygrib data unfortunately) or how make matplotlib close gap, me out of problem. maybe function "addcyclic" help, don't know how.
edit: solved problem, see answer.
so here code producing problem:
#!/usr/bin/python3 import os, sys, datetime, string abc import abcmeta, abstractmethod import numpy np import numpy.ma ma scipy.ndimage.filters import minimum_filter, maximum_filter import pygrib netcdf4 import dataset pylab import * import matplotlib.pyplot plt mpl_toolkits.basemap import basemap, addcyclic, shiftgrid import laplacefilter import mpl_util class plot(basemap): def __init__(self, basemapparams): super().__init__(**basemapparams) self.layers = [] def addlayer(self, layer): self.layers.append(layer) def plot(self, data): layer in self.layers: layer.plot(self, data) plt.title('plot') plt.show() class layer(metaclass=abcmeta): def __init__(self): pass @abstractmethod def plot(self, plot, data): return notimplemented class backgroundlayer(layer): def __init__(self, bgtype, coords): #possible bgtype values: borders, topo, both self.bgtype = bgtype self.lonstart = coords[0] self.lonend = coords[1] self.latstart = coords[2] self.latend = coords[3] def plot(self, plot, data): [...] def findsubsetindices(self,min_lat,max_lat,min_lon,max_lon,lats,lons): [...] class legendlayer(layer): def __init__(self): pass class gribdatalayer(layer, metaclass=abcmeta): def __init__(self, varname, level, clevs, cmap, factor): self.varname = varname self.level = level self.clevs = clevs self.cmap = cmap self.factor = factor def plot(self, plot, data): #depending on height want use, have change index indexes = {1000:0, 2000:1, 3000:2, 5000:3, 7000:4, 10000:5, 15000:6, 20000:7, 25000:8, 30000:9, 35000:10, 40000:11, 45000:12, 50000:13, 55000:14, 60000:15, 65000:16, 70000:17, 75000:18, 80000:19, 85000:20, 90000:21, 92500:22, 95000:23, 97500:24, 100000:25, 0:0} selecteddata = data.select(name = self.varname)[indexes[self.level]] lats, lons = selecteddata.latlons() layerdata = selecteddata.values*self.factor x, y = plot(lons, lats) # compute map proj coordinates. self.filllayer(plot, x, y, layerdata, self.clevs, self.cmap) @abstractmethod def filllayer(self, plot, x, y, layerdata, clevs, cmap): return notimplemented class contourlayer(gribdatalayer): def __init__(self, varname, level, clevs, cmap, factor, linewidth=1.5, fontsize=15, fmt="%3.1f", inline=0,labelcolor = 'k'): self.linewidth = linewidth self.fontsize = fontsize self.fmt = fmt self.inline = inline self.labelcolor = labelcolor super().__init__(varname, level, clevs, cmap, factor) def filllayer(self, plot, x, y, layerdata, clevs, cmap): # contour data on map. cs = plot.contour(x,y,layerdata,clevs,colors = cmap,linewidths = self.linewidth) plt.clabel(cs, clevs, fontsize = self.fontsize, fmt = self.fmt, inline = self.inline, colors = self.labelcolor) if self.varname == "pressure reduced msl": self.plothighslows(plot,layerdata,x,y) def plothighslows(self,plot,layerdata,x,y): [...] class contourfilledlayer(gribdatalayer): def __init__(self, varname, level, clevs, cmap, factor, extend="both"): self.extend = extend super().__init__(varname, level, clevs, cmap, factor) def filllayer(self, plot, x, y, layerdata, clevs, cmap): # contourfilled data on map. cs = plot.contourf(x,y,layerdata,levels=clevs,cmap=cmap,extend=self.extend) #cbar = plot.colorbar.colorbarbase(cs) [...] ger_coords = [4.,17.,46.,56.] eu_coords = [-25.,57.,22.,70.] ### choose data data = pygrib.open('gfs.t12z.mastergrb2f03') ### 500hpa europe coords = eu_coords plot1 = plot({"projection":"lcc","resolution":"h","rsphere":(6378137.00,6356752.3142), "area_thresh": 1000., "llcrnrlon":coords[0],"llcrnrlat":coords[2],"urcrnrlon":coords[1],"urcrnrlat":coords[3], "lon_0":(coords[0]+coords[1])/2.,"lat_0":(coords[2]+coords[3])/2.}) clevs = range(480,600,4) cmap = plt.cm.nipy_spectral factor = .1 extend = "both" level = 50000 layer1 = contourfilledlayer('geopotential height', level, clevs, cmap, factor, extend) clevs = [480.,552.,600.] linewidth = 2. fontsize = 14 fmt = "%d" inline = 0 labelcolor = 'k' layer2 = contourlayer('geopotential height', level, clevs, 'k', factor, linewidth, fontsize, fmt, inline, labelcolor) level = 0 clevs = range(800,1100,5) factor = .01 linewidth = 1.5 inline = 0 labelcolor = 'k' layer3 = contourlayer('pressure reduced msl', level, clevs, 'w', factor, linewidth, fontsize, fmt, inline, labelcolor) plot1.addlayer(backgroundlayer('borders', coords)) plot1.addlayer(layer1) plot1.addlayer(layer2) plot1.addlayer(layer3) plot1.plot(data)
i solved myself 2 months later:
matplotlib doesn't fill area if longitude range 0 359.75 because ends there matplotlibs point of view. solved dividing data , stacking it.
selecteddata_all = data.select(name = "temperature")[0] selecteddata1, lats1, lons1 = selecteddata_all.data(lat1=20,lat2=60,lon1=335,lon2=360) selecteddata2, lats2, lons2 = selecteddata_all.data(lat1=20,lat2=60,lon1=0,lon2=30) lons = np.hstack((lons1,lons2)) lats = np.hstack((lats1,lats2)) selecteddata = np.hstack((selecteddata1,selecteddata2))
no white area left of 0° anymore.
i don't know whether there fix if wanna plot whole hemisphere (0 359.75 deg).
Comments
Post a Comment