I am using python 3.6 to plot precipitation data from CMIP5, the file I have downloaded is a netCDF4 file. I have used this code on another similar file and it worked out fine so I am not sure what the problem is. I am not receiving any error message with this code, it just displays a world map that is all one color when it should be a variety of colors. The variables found in this file are time, time_bnds, lat, lat_bnds, lon, lon_bnds, and prc. prc is the precipitation variable and the one I an interested in plotting. Any ideas would be helpful, Thank you!
Here is my code
from mpl_toolkits.basemap import Basemap, cm
from netCDF4 import Dataset as NetCDFFile
import matplotlib.pyplot as plt
nc = NetCDFFile('filename.nc','r')
p = nc.variables['prc']
data = p[:,:,0]
fig = plt.figure(figsize=(8,8))
ax = fig.add_axes([0.1,0.1,0.8,0.8])
m = Basemap(projection='cyl',lon_0=180,lat_0=0,resolution='l')
m.drawcoastlines()
m.drawstates()
m.drawcountries()
ny = data.shape[0]; nx = data.shape[1]
lons, lats = m.makegrid(nx,ny)
x,y = m(lons, lats) # compute map proj coordinates.
cs=plt.contourf(x,-y,data,range(0,1000,10),cmap=cm.s3pcpn,latlon=True)
cbar = m.colorbar(cs,location='bottom',pad="5%")
cbar.set_label('mm')
plt.show()
Related
I have a 3-dimensional xarray DataArray of changes in surface temperature with coordinates of time, lat and lon. I am visualizing the data using Cartopy. You can find the 125 MB file here.
While producing plots of time-averages over different periods, I've found that I'm unable to produce orthographic projections when including certain time steps, such as the 132nd (index 131) time. Here is a plot of the time average from 0 to 130:
But this happens when I instead perform the time average from 0 to 131:
Here is the code I used to produce the plots:
# import statements
import cartopy.crs as ccrs
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
from cartopy.util import add_cyclic_point
%matplotlib inline
%config InlineBackend.figure_format = "jpg"
# read in data
ens_mean = xr.open_dataarray('temp_changes_ens_mean.nc')
# time average subset of data
to_plot = ens_mean.isel(time=slice(None,131)).mean(dim='time') # change 130 to 131 to break cartopy
# add cyclic point to avoid white lines
data = to_plot
lon = to_plot.coords['lon']
lon_idx = data.dims.index('lon')
wrap_data, wrap_lon = add_cyclic_point(data.values, coord=lon, axis=lon_idx)
# make an orthographic plot centered on north pole
fig = plt.figure(figsize=(4.5,3.5))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(0, 90))
ax.coastlines()
im = ax.contourf(wrap_lon, to_plot.lat, wrap_data,
transform=ccrs.PlateCarree())
# add colorbar
cb = fig.colorbar(im,orientation='horizontal',shrink=0.5,pad=0.05)
cb.ax.tick_params(labelsize=8)
cb.set_label('ΔSAT (K)',fontsize=8)
plt.tight_layout(w_pad=0.05)
plt.show()
This occurs whether I add a cyclic point or not. I am able to make quick plots of the data using matplotlib or xarray's built-in plotting without error. I've already checked for NaN values in the data. Lastly, if I remove the transform argument in the contourf line, it is able to produce a coherent plot, which leads me to think it is the transformation step that produces this odd plot.
Thanks for the help!
You can use ax.set_global() method to reset the coordinate limits:
#!/usr/bin/env ipython
# --------------------------------------------
import cartopy.crs as ccrs
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
from cartopy.util import add_cyclic_point
# --------------------------------------------------------------------------------------
#%matplotlib inline
#%config InlineBackend.figure_format = "jpg"
# read in data
ens_mean = xr.open_dataarray('temp_changes_ens_mean.nc')
# time average subset of data
to_plot = ens_mean.isel(time=slice(None,131)).mean(dim='time') # change 130 to 131 to break cartopy
# add cyclic point to avoid white lines
data = to_plot
lon = to_plot.coords['lon']
lon_idx = data.dims.index('lon')
wrap_data, wrap_lon = add_cyclic_point(data.values, coord=lon, axis=lon_idx)
# ------------------------------------------------------------------
# this is not working:
xlims = (np.min(ens_mean['lon']),np.max(ens_mean['lon']));
ylims = (np.min(ens_mean['lat']),np.max(ens_mean['lat']));
# ------------------------------------------------------------------
lon = to_plot.coords['lon']
# ====================================================================================
# make an orthographic plot centered on north pole
# Let us make a working/satisfying plot:
fig = plt.figure(figsize=(4.5,3.5))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(0, 90))
ax.coastlines()
im = ax.contourf(wrap_lon, to_plot.lat, wrap_data,
transform=ccrs.PlateCarree())
# -----------------------------------------------------------
# add colorbar
cb = fig.colorbar(im,orientation='horizontal',shrink=0.5,pad=0.05)
cb.ax.tick_params(labelsize=8)
cb.set_label('ΔSAT (K)',fontsize=8)
plt.tight_layout(w_pad=0.05)
ax.set_global();
#ax.set_xlim(xlims);
#ax.set_ylim(ylims);
plt.show()
I have a grid of data points with a value of latitude/longitude for each row/column. I want to plot this to give a nice looking map. How do I go about this? I have tried converting the latitude/longitude row/column 'titles' to cartesian but cant get this to work.
from netCDF4 import Dataset
from mpl_toolkits.basemap import Basemap, cm
import matplotlib.pyplot as plt
general_file = 'data\ir2_20160815_114117_232_l3b_v10.nc'
file_data = Dataset(general_file)
lat = file_data.variables['latitude']
lon = file_data.variables['longitude']
rad = file_data.variables['radiance']
latitudes = lat[:]
longitudes = lon[:]
radiances = rad[0]
x= longitudes
y=latitudes
z = radiances
plt.contourf(x, y, z,25,cmap='Greys')
plt.title(general_file)
plt.colorbar()
plt.show()
The data file was downloaded from https://darts.isas.jaxa.jp/pub/pds3/extras/vco_ir2_l3_v1.0/vcoir2_7001/data/l3b/netcdf/r0024/
You could do this using my package ncplot (https://pypi.org/project/ncplot/).
import ncplot
ncplot.view('data\ir2_20160815_114117_232_l3b_v10.nc', "radiance")
Hello everyone.In the picture you can see a sample of my code(it repeats for i==6),and the outputs.Can somone tell me how to add coastlines/boundaries to maps?"ax.coastlines() failed. Thank you
I think the problem is that your axes is not a geoAxes. To make it a geoAxes you have to tell matplotlib what projection (e.g. PlateCarree) you would like to use.
What you could do is using the cartopy library and adding the projection key word to your subplot. See example below:
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
# Create sample data
lon = np.arange(129.4, 153.75+0.05, 0.25)
lat = np.arange(-43.75, -10.1+0.05, 0.25)
data = 10 * np.random.rand(len(lat), len(lon))
data_array = xr.Dataset({"DC": (["lat", "lon"], data),
'DMC': (["lat", "lon"], data),
'FFMC': (["lat", "lon"], data)},
coords={"lon": lon,"lat": lat})
# Just checking the datasets are not empty
print(data_array)
#< Plotting
fig, axes = plt.subplots(nrows=3, ncols=3, subplot_kw={'projection': ccrs.PlateCarree()}) # Use PlateCarree projection
data_array['DC'].plot(ax=axes[0,0], cmap='Spectral_r', add_colorbar=True, extend='both')
axes[0,0].coastlines() # Add coastlines
I am trying to render a polygon using python matplot Basemap lib.
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
def render_polygon(lat, long):
map = Basemap(llcrnrlon=-10,llcrnrlat=35,urcrnrlon=35,urcrnrlat=60.,
resolution=None, projection='tmerc', lat_0 =
8.30, lon_0 = 3.46)
map.plot(lat, long, marker=None,color='m')
plt.show()
lat = [56.1304, 55.1304, 54.1304, 53.1304, 52.1304]
long = [106.3468, 107.3468, 105.3468, 104.3468, 103.3468]
render_polygon(lat, long)
When I run the program passing the latitude longitude I see an empty rectangle.
Can someone point out what am I doing incorrect?
You need to transform coordinates in the process.
Try changing
map.plot(lat, long, marker=None, color='m')
to
map.plot(*map(long, lat), marker=None, color='m')
The code *map(long, lat) does the required coordinate transformation, and spreads the result to xs, ys in that place.
Edit 1
The original code have been edited to get appropriate data extent, proper projection parameters.
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
def render_polygon(lat, long):
map = Basemap(llcrnrlon=103, llcrnrlat=50, urcrnrlon=107.5, urcrnrlat=60.,
resolution='c', projection='merc',
lat_0 = 50, lon_0 = 105)
map.plot(*map(long, lat), marker=None, color='m')
#map.drawcoastlines(linewidth=0.7)
plt.show()
lat = [56.1304, 55.1304, 54.1304, 53.1304, 52.1304]
long = [106.3468, 107.3468, 105.3468, 104.3468, 103.3468]
render_polygon(lat, long)
The output plot:
I'm very new to Python but have been learning lots over the last few months. I'm trying to plot NOAA swell height data from a grib2 file located here: ftp://ftpprd.ncep.noaa.gov/pub/data/nccf/com/wave/prod/wave.20140122/nww3.t06z.grib.grib2
I use Basemap and a tutorial that I found on a Basemap forum.
A minimum working example is below, but I'm getting some strange white boxes around the coastline.
import Nio
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np
f = Nio.open_file('nww3.t12z.grib(2).grib2')
lons = f.variables['lon_0'][:]
lats = f.variables['lat_0'][::-1] # flip latitudes so data goes S-->N
times = f.variables['forecast_time0'][:]
ntime = 5
data = f.variables['HTSGW_P0_L1_GLL0'][ntime,::-1]
fig = plt.figure(figsize=(16,16))
m = Basemap(llcrnrlon=-35.,llcrnrlat=42.,urcrnrlon=5.,urcrnrlat=65.,
projection='lcc',lat_1=10.,lat_2=15.,lon_0=10.,
resolution ='h',area_thresh=1000.)
x, y = m(*np.meshgrid(lons, lats))
m.fillcontinents(color='#477519')
m.drawcoastlines(linewidth=0.5, color='k', antialiased=1, ax=None, zorder=None )
m.contourf(x, y, data, np.arange(0,9.9,0.1))
plt.show()
This is the result (the top panel; I would like it to look like the bottom panel): http://oi43.tinypic.com/s2s3m0.jpg
Sorry I don't have enough points to post images.
Thanks in advance,
Al