Lines not plotting on graph using Python/Basemap - python

Sorry if this question is simple I'm a newb to using Python and Basemap. Anyway I'm trying to plot the path of 20 hurricanes on a map (graph). The map itself and the legend show up perfectly but the paths of the hurricanes do not. Also I'm not getting any traceback messages but I think I have an idea of where my problem may be. Could someone please tell me where I went wrong.
Here's a sample of the csv file:
Year, Name, Type, Latitude, Longitude
1957,AUDREY,HU, 21.6, 93.3
1957,AUDREY,HU,22.0, 93.4
1957,AUDREY,HU,22.6, 93.5
1969,AUDREY,HU,28.2,99.6
1957,AUDREY,HU,26.5,93.8
1957,AUDREY,HU,27.9,93.8
1957,AUDREY,HU,29.3,95
1957,AUDREY,HU,27.9,93.8
1957,AUDREY,HU,29.3,93.8
1957,AUDREY,HU,30.7,93.5
1969,CAMILLE,HU, 21.6,99.3
1969,CAMILLE,HU,22.0,98.4
1969,CAMILLE,HU,22.6,90.5
1969,CAMILLE,HU,23.2,93.6
Here's the code I have so far:
import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import csv, os, scipy
import pandas
from PIL import *
data = np.loadtxt('louisianastormb.csv',dtype=np.str,delimiter=',',skiprows=1)
'''print data'''
fig = plt.figure(figsize=(12,12))
ax = fig.add_axes([0.1,0.1,0.8,0.8])
m = Basemap(llcrnrlon=-100.,llcrnrlat=0.,urcrnrlon=-20.,urcrnrlat=57.,
projection='lcc',lat_1=20.,lat_2=40.,lon_0=-60.,
resolution ='l',area_thresh=1000.)
m.bluemarble()
m.drawcoastlines(linewidth=0.5)
m.drawcountries(linewidth=0.5)
m.drawstates(linewidth=0.5)
# Creates parallels and meridians
m.drawparallels(np.arange(10.,35.,5.),labels=[1,0,0,1])
m.drawmeridians(np.arange(-120.,-80.,5.),labels=[1,0,0,1])
m.drawmapboundary(fill_color='aqua')
color_dict = {'AUDREY': 'red', 'ETHEL': 'white', 'BETSY': 'yellow','CAMILLE': 'blue', 'CARMEN': 'green','BABE': 'purple', }
colnames = ['Year','Name','Type','Latitude','Longitude']
data = pandas.read_csv('louisianastormb.csv', names=colnames)
names = list(data.Name)
lat = list(data.Latitude)
long = list(data.Longitude)
colorName = list(data.Name)
#print lat
#print long
lat.pop(0)
long.pop(0)
colorName.pop(0)
latitude= map(float, lat)
longitude = map(float, long)
x, y = m(latitude,longitude)
#Plots points on map
for colorName in color_dict.keys():
plt.plot(x,y,linestyle ='-',label=colorName,color=color_dict[colorName], linewidth=5 )
lg = plt.legend()
lg.get_frame().set_facecolor('grey')
plt.show()

two (okay I lied, should be there) problems with your code
i, your input longitude should be negative to be within the boundary you defined for your basemap, so add this after before converting to x and y
longitude = [-i for i in longitude]
ii, your coordinate conversion line is wrong, you should swap lon and lat in the argument list
x, y = m(longitude, latitude)
instead of
x, y = m(latitude,longitude)
EDIT:
okay, the second question that OP posted in the comments, please check the complete code below and please pay attention to the changes I've made compared to yours
# Last-modified: 21 Oct 2013 05:35:16 PM
import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import csv, os, scipy
import pandas
from PIL import *
data = np.loadtxt('louisianastormb.csv',dtype=np.str,delimiter=',',skiprows=1)
'''print data'''
fig = plt.figure(figsize=(12,12))
ax = fig.add_axes([0.1,0.1,0.8,0.8])
m = Basemap(llcrnrlon=-100.,llcrnrlat=0.,urcrnrlon=-20.,urcrnrlat=57.,
projection='lcc',lat_1=20.,lat_2=40.,lon_0=-60.,
resolution ='l',area_thresh=1000.)
m.drawcoastlines(linewidth=0.5)
m.drawcountries(linewidth=0.5)
m.drawstates(linewidth=0.5)
# m.bluemarble(ax=ax)
# Creates parallels and meridians
m.drawparallels(np.arange(10.,35.,5.),labels=[1,0,0,1])
m.drawmeridians(np.arange(-120.,-80.,5.),labels=[1,0,0,1])
m.drawmapboundary(fill_color='aqua')
color_dict = {'AUDREY': 'red', 'ETHEL': 'white', 'BETSY': 'yellow','CAMILLE': 'blue', 'CARMEN': 'green','BABE': 'purple', }
colnames = ['Year','Name','Type','Latitude','Longitude']
data = pandas.read_csv('louisianastormb.csv', names=colnames)
names = list(data.Name)
lat = list(data.Latitude)
long = list(data.Longitude)
colorNames = list(data.Name)
#print lat
#print long
lat.pop(0)
long.pop(0)
colorNames.pop(0)
latitude= map(float, lat)
longitude = map(float, long)
# added by nye17
longitude = [-i for i in longitude]
# x, y = m(latitude,longitude)
x, y = m(longitude,latitude)
# convert to numpy arrays
x = np.atleast_1d(x)
y = np.atleast_1d(y)
colorNames = np.atleast_1d(colorNames)
#Plots points on map
for colorName in color_dict.keys():
plt.plot(x[colorName == colorNames],y[colorName == colorNames],linestyle ='-',label=colorName,color=color_dict[colorName], linewidth=5 )
lg = plt.legend()
lg.get_frame().set_facecolor('grey')
plt.show()

I think your difficulty is not so much in Basemap as in the plotting. Instead of plotting the entire x/y data set you need to find the x/y points corresponding on hurricane Z. Then plot only those points in a certain color c. Then find the points corresponding to the next hurricane etc...
The below, while not using the Basemap data structure should provide a starting point for plotting subsets of points based on some selector vector.
#given a list of x,y coordinates with a label we'll plot each line individually
#first construct some points to plot
x1 = [1,1.1,1.2,1.3, 2.0,2.2,2.3, 4,3.9,3.8,3.7]
y1 = [5,5.1,5.2,5.3, 6.0,6.2,6.3, 2,2.1,2.2,2.3]
pointNames = []
#generate some labels
pointNames.extend(['a']*4)
pointNames.extend(['b']*3)
pointNames.extend(['c']*4)
#make things easy by casting to numpy arrays to allow for easier indexing
x1 = numpy.array(x1)
y1 = numpy.array(y1)
pointNames = numpy.array(pointNames)
for elem in ['a','b','c']:
selector = pointNames==elem
subsetX = x1[selector]
subsetY = y1[selector]
#now plot subsetX vs subsetY in color Z
plot(subsetX,subsetY,'*-')
show()

Related

changing colorbar sensitivity

I re edited the question in order to make it more clear with what I need help. So I have the following code so far
#import the libraries
import netCDF4 as nc
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
#check what variables are included
# in our case : dict_keys(['time', 'time_bnds', 'lat', 'lat_bnds', 'lon', 'lon_bnds', 'height', 'tas'])
print(data.variables.keys())
#extract the data
lats = data.variables['lat'][:]
lons = data.variables['lon'][:]
time = data.variables['time'][:]
te = data.variables['tas'][:]-273.5
#extract the coordinates we want to plot (Italy)by inputting lower #left and top right coordinates
italy = Basemap(projection='merc',
#ITALY
llcrnrlon= 6.63,
llcrnrlat= 35.29,
urcrnrlon= 18.78,
urcrnrlat= 47.09,
resolution= 'f')
#create the plot
lon,lat =np.meshgrid(lons,lats)
x,y=italy(lon,lat)
c_scheme = italy.pcolor(x,y,np.squeeze(te[0,:,:]), cmap ='jet')
italy.drawcoastlines()
italy.drawstates()
italy.drawcounties()
cbar = italy.colorbar(c_scheme, location='right',pad='10%')
plt.title('KIOST-ESM')
plt.show()
which creates the following heat map
Now what I want is to make the plot identify(colour) smaller differences between the temperatures. However I do not know exactly how to find the min and max value of my area that I am investigating (this time it is Italy). My variable te that has the temperatures is of the type : numpy.ma.core.MaskedArray with shape (9125, 160, 320) [time,lon,lat]
Setting vmin and vmax values should solve this. please try
min_height = int(np.min(np.squeeze(te[0,:,:])))
max_height = int(np.max(np.squeeze(te[0,:,:])))
c_scheme = italy.pcolor(x,y,np.squeeze(te[0,:,:]), cmap ='jet', vmin=min_height, vmax=max_height)
In the case that the te array holds is bigger than the mesh in x and y, I would try doing the following:
min_height = int(np.min(np.squeeze(te[0,x,y])))
max_height = int(np.max(np.squeeze(te[0,x,y])))

Plot 4D data heatmap in Python

hey how can I plot a 2D heatmap in 3D? Now I create a python script to make a 2D Heatmap Plot with data from CSV (CSV format: x,y,z,v).
For example:
First csv
0,000;-110,000;110,000;0,101
Second csv
0,000;-66,000;110,000;0,104
Third csv
0,000;-22,000;110,000;0,119
....
In this example, it is a heatmap in xz-plane and I create e.g. five more plots, so that I can insert six xz-plane Plots in a 3D room.
In 4D heatmap plot with matplotlib there is a very nice example for doing it. But I don't know how to use it in my case.
import numpy as np
import os
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
'Create a list for every parameter'
x = []
y = []
z = []
v = []
file_path = "path/."
'Insert data from csv into lists'
for root, dirs, files in os.walk(file_path, topdown=False):
for name in files:
if name[-4:] != '.csv': continue
with open(os.path.join(root, name)) as data:
data = np.genfromtxt((line.replace(',', '.') for line in data), delimiter=";")
if data[1] == 22:
x.append(data[0])
y.append(data[1])
z.append(data[2])
v.append(data[3])
'Create axis data'
xi = np.linspace(min(x), max(x), 1000)
zi = np.linspace(min(z), max(z), 1000)
vi = griddata((x, z), v, (xi[None,:], zi[:,None]), method='cubic')
'Create the contour plot'
CS = plt.contourf(xi, zi, vi, 20, cmap=plt.cm.rainbow)
plt.title("Heatmap xz-plane", y=1.05,
fontweight="bold")
plt.xlabel("length x in cm")
plt.xticks(np.arange(0, 201, step=40))
plt.ylabel("height z in cm")
plt.yticks(np.arange(110, 251, step=20))
cbar = plt.colorbar()
cbar.set_label("velocity v in m/s", labelpad=10)
plt.savefig('testplot.png', dpi=400)
plt.show()
Satisfying the request of #keepAlive wishing to see the result of his untested answer... :
it actually works great :-)
Disclaimer: I am the author of the cited example, so I think that copying/pasting myself is not really a problem.
Note that your dataset does not look (at least) 3-dimensional. But I will assume there is an unwilling selection bias.
You first need to aggregate your "points" per level of altitude, which I assume is the third component of your vectors. They will be constitutive of your planes once gathered.
# libraries
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import scipy.interpolate as si
from matplotlib import cm
import collections as co # <------------------
import pandas as pd
import numpy as np
planes = co.defaultdict(list)
for root, dirs, files in os.walk(file_path, topdown=False):
# [...]
# [...]
# [...]
# [...]
# [...]
level = data[2] # <------ third component.
planes[level].append(data)
Now, at that stage, we have a list of arrays per level. Let's define our grids_maker function
def grids_maker(arrays_list, colnames=list('xyzg')):
# 0- The idea behind `list('xyzg')` is only to change the order
# of names, not the names as such. In case for example you
# want to use another component than the third to organize
# your planes.
# 1- Instantiate a dataframe so as to minimize the modification
# of the function copied/pasted pasted from
# https://stackoverflow.com/a/54075350/4194079
# 2- Pandas is also going to do some other jobs for us, such as
# stacking arrays, etc....
df = pd.DataFrame(arrays_list, columns=colnames)
# Make things more legible
xy = df.loc[:, ['x', 'y']]
x = xy.x
y = xy.y
z = df.z
g = df.g
reso_x = reso_y = 50
interp = 'cubic' # or 'nearest' or 'linear'
# Convert the 4d-space's dimensions into grids
grid_x, grid_y = np.mgrid[
x.min():x.max():1j*reso_x,
y.min():y.max():1j*reso_y
]
grid_z = si.griddata(
xy, z.values,
(grid_x, grid_y),
method=interp
)
grid_g = si.griddata(
xy, g.values,
(grid_x, grid_y),
method=interp
)
return {
'x' : grid_x,
'y' : grid_y,
'z' : grid_z,
'g' : grid_g,
}
Let's use grids_maker over our list of arrays and get the extrema of each z-level's 4th dimension.
g_mins = []
g_maxs = []
lgrids = {}
for level, arrays_list in planes.items():
lgrids[level] = grids = grids_maker(arrays_list)
g_mins.append(grids['g'].min())
g_maxs.append(grids['g'].max())
Let's create our (all-file unifying) color-scale and show the plot.
# Create the 4th color-rendered dimension
scam = plt.cm.ScalarMappable(
norm=cm.colors.Normalize(min(g_mins), max(g_maxs)),
cmap='jet' # see https://matplotlib.org/examples/color/colormaps_reference.html
)
fig = plt.figure()
ax = fig.gca(projection='3d')
for grids in lgrids.values():
scam.set_array([])
ax.plot_surface(
grids['x'], grids['y'], grids['z'],
facecolors = scam.to_rgba(grids['g']),
antialiased = True,
rstride=1, cstride=1, alpha=None
)
plt.show()
I would be glad to see the result.

How to use geopandas to plot latitude and longitude on a more detailed map with by using basemaps?

I am trying to plot some latitude and longitudes on the map of delhi which I am able to do by using a shape file in python3.8 using geopandas
Here is the link for the shape file:
https://drive.google.com/file/d/1CEScjlcsKFCgdlME21buexHxjCbkb3WE/view?usp=sharing
Following is my code to plot points on the map:
lo=[list of longitudes]
la=[list of latitudes]
delhi_map = gpd.read_file(r'C:\Users\Desktop\Delhi_Wards.shp')
fig,ax = plt.subplots(figsize = (15,15))
delhi_map.plot(ax = ax)
geometry = [Point(xy) for xy in zip(lo,la)]
geo_df = gpd.GeoDataFrame(geometry = geometry)
print(geo_df)
g = geo_df.plot(ax = ax, markersize = 20, color = 'red',marker = '*',label = 'Delhi')
plt.show()
Following is the result:
Now this map is not very clear and anyone will not be able to recognise the places marked so i tried to use basemap for a more detailed map through the following code:
df = gpd.read_file(r'C:\Users\Jojo\Desktop\Delhi_Wards.shp')
new_df = df.to_crs(epsg=3857)
print(df.crs)
print(new_df.crs)
ax = new_df.plot()
ctx.add_basemap(ax)
plt.show()
And following is the result:
I am getting the basemap but my shapefile is overlapping it. Can i get a map to plot my latitudes and longitudes where the map is much more detailed with names of places or roads or anything similar to it like in google maps or even something like the map which is being overlapped by the blue shapefile map?
Is it possible to plot on a map like this??
https://www.researchgate.net/profile/P_Jops/publication/324715366/figure/fig3/AS:618748771835906#1524532611545/Map-of-Delhi-reproduced-from-Google-Maps-12.png
use zorder parameter to adjust the layers' orders (lower zorder means lower layer), and alpha to the polygon. anyway, I guess, you're plotting df twice, that's why it's overlapping.
here's my script and the result
import geopandas as gpd
import matplotlib.pyplot as plt
import contextily as ctx
from shapely.geometry import Point
long =[77.2885437011719, 77.231931, 77.198767, 77.2750396728516]
lat = [28.6877899169922, 28.663863, 28.648287, 28.5429172515869]
geometry = [Point(xy) for xy in zip(long,lat)]
wardlink = "New Folder/wards delimited.shp"
ward = gpd.read_file(wardlink, bbox=None, mask=None, rows=None)
geo_df = gpd.GeoDataFrame(geometry = geometry)
ward.crs = {'init':"epsg:4326"}
geo_df.crs = {'init':"epsg:4326"}
# plot the polygon
ax = ward.plot(alpha=0.35, color='#d66058', zorder=1)
# plot the boundary only (without fill), just uncomment
#ax = gpd.GeoSeries(ward.to_crs(epsg=3857)['geometry'].unary_union).boundary.plot(ax=ax, alpha=0.5, color="#ed2518",zorder=2)
ax = gpd.GeoSeries(ward['geometry'].unary_union).boundary.plot(ax=ax, alpha=0.5, color="#ed2518",zorder=2)
# plot the marker
ax = geo_df.plot(ax = ax, markersize = 20, color = 'red',marker = '*',label = 'Delhi', zorder=3)
ctx.add_basemap(ax, crs=geo_df.crs.to_string(), source=ctx.providers.OpenStreetMap.Mapnik)
plt.show()
I don't know about google maps being in the contextily, I don't think it's available. alternatively, you can use OpenStreetMap base map which shows quite the same toponym, or any other basemap you can explore. use `source` keyword in the argument, for example, `ctx.add_basemap(ax, source=ctx.providers.OpenStreetMap.Mapnik)` . here's how to check the available providers and the map each providers provides:
>>> ctx.providers.keys()
dict_keys(['OpenStreetMap', 'OpenSeaMap', 'OpenPtMap', 'OpenTopoMap', 'OpenRailwayMap', 'OpenFireMap', 'SafeCast', 'Thunderforest', 'OpenMapSurfer', 'Hydda', 'MapBox', 'Stamen', 'Esri', 'OpenWeatherMap', 'HERE', 'FreeMapSK', 'MtbMap', 'CartoDB', 'HikeBike', 'BasemapAT', 'nlmaps', 'NASAGIBS', 'NLS', 'JusticeMap', 'Wikimedia', 'GeoportailFrance', 'OneMapSG'])
>>> ctx.providers.OpenStreetMap.keys()
dict_keys(['Mapnik', 'DE', 'CH', 'France', 'HOT', 'BZH'])
I don't know geopandas. The idea I'm suggesting uses only basic python and matplotlib. I hope you can adapt it to your needs.
The background is the following map. I figured out the GPS coordinates of its corners using google-maps.
The code follows the three points of my remark. Note that the use of imread and imshow reverses the y coordinate. This is why the function coordinatesOnFigur looks non-symmetrical in x and y.
Running the code yields the map with a red bullet near Montijo (there is a small test at the end).
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib import patches
from matplotlib.widgets import Button
NE = (-8.9551, 38.8799)
SE = (-8.9551, 38.6149)
SW = (-9.4068, 38.6149)
NW = (-9.4068, 38.8799)
fig = plt.figure(figsize=(8, 6))
axes = fig.add_subplot(1,1,1, aspect='equal')
img_array = plt.imread("lisbon_2.jpg")
axes.imshow(img_array)
xmax = axes.get_xlim()[1]
ymin = axes.get_ylim()[0] # the y coordinates are reversed, ymax=0
# print(axes.get_xlim(), xmax)
# print(axes.get_ylim(), ymin)
def coordinatesOnFigure(long, lat, SW=SW, NE=NE, xmax=xmax, ymin=ymin):
px = xmax/(NE[0]-SW[0])
qx = -SW[0]*xmax/(NE[0]-SW[0])
py = -ymin/(NE[1]-SW[1])
qy = NE[1]*ymin/(NE[1]-SW[1])
return px*long + qx, py*lat + qy
# plotting a red bullet that corresponds to a GPS location on the map
x, y = coordinatesOnFigure(-9, 38.7)
print("test: on -9, 38.7 we get", x, y)
axes.scatter(x, y, s=40, c='red', alpha=0.9)
plt.show()

basemap & contourf, Python

I have a set of satellite data file here, I created a grid for lat & lon and a 2D array for Ozone values.
I know that in order to plot the contourf of the data in a map I need the projection coordinates, but I can't get find a way around it as my grid is not square (144x24). I am covering the geographical area (0 to 360; -30 to 30) and I require square pixels.
The data is quite long to post it but this is my code so far,
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from mpl_toolkits.basemap import Basemap, cm
%matplotlib inline
path = '/home/rafaella/month_files_CSV/O3_COLUMNS_MATCHED_fv0005_200306.csv'
df = pd.read_csv(path, skiprows=1)
df = pd.read_csv(path, delim_whitespace=True)
lat = np.array(df['AVG_LAT'])
lon = np.array(df['AVG_LON'])
toc = np.array(df['TROP_COL'])
#new grid for lon[0,360] lat[-30,30]
lomin = 0
lomax = 360
lamin = -30
lamax = 30
stp = 2.5
loc_lon = np.zeros(int((lomax-lomin)/stp))
loc_lat = np.zeros(int((lamax-lamin)/stp))
for i in range(0,len(loc_lon)):
loc_lon[i] = i*stp +lomin
for j in range(0,len(loc_lat)):
loc_lat[j] = j*stp +lamin
mtoc_local = np.zeros((len(loc_lon),len(loc_lat)))
sdtoc_local = np.zeros((len(loc_lon),len(loc_lat)))
mtoc_local[:,:] = np.nan
sdtoc_local[:,:] = np.nan
for i in range (0, len(loc_lon)):
for j in range (0,len(loc_lat)):
ix = np.where((lon>=loc_lon[i])& (lat>=loc_lat[j]) & (lon<loc_lon[i]+stp) & (lat<loc_lat[j]+stp))[0]
mtoc_local[i,j]=np.nanmean(toc[ix])
sdtoc_local[i,j]=np.nanstd(toc[ix])
fig = plt.figure(figsize=(20, 5))
map = Basemap(llcrnrlon=0,llcrnrlat=-30, urcrnrlon=360.,urcrnrlat=30.,\
rsphere=(6378137.00,6356752.3142),\
resolution='l',projection='merc',\
lat_0=0,lon_0=-30.,lat_ts=30.)
map.drawcoastlines()
# draw parallels
map.drawparallels(np.arange(-30,30,10),labels=[1,1,0,1])
# draw meridians
map.drawmeridians(np.arange(-180,180,20),labels=[1,1,0,1])
map = plt.contourf(loc_lon, loc_lat , mtoc_local.T, vmin=210, vmax=350, cmap='RdPu')
plt.colorbar(orientation='horizontal', ticks=[200, 220, 240, 260, 280, 300, 320, 340] )
plt.title('Tropical TOC monthly mean 06,2009')
plt.show()
It plots very well the map OR the data but not both. here an image of both separately
map
real data
I am very new to python, I started a month ago, so it is still not familiar to me all the functions and libraries.
Your code has two problems. First you have to apply the projection on your coordinates which is done using x,y = map(lon, lat). However, this will raise an error in your case since the dimensions of loc_lon and loc_lat are different. Instead of passing x and y vectors to the contourf function you can pass arrays with the same shape as z (mtoc_local.T). You can use np.meshgrid to create those. Long story short, replace the line with the contourf command with the following three lines
X, Y = np.meshgrid(loc_lon, loc_lat)
x,y = map(X,Y)
map = plt.contourf(x, y , mtoc_local.T, vmin=210, vmax=350, cmap='RdPu')
and the result looks like this

plot gebco data in python basemap

I have downloaded some gebco bathymetry data as a netCDF file. I would like to plot it with python-basemap. I have tried,
import netCDF4
from mpl_toolkits.basemap import Basemap
# Load data
dataset = netCDF4.Dataset('/home/david/Desktop/GEBCO/gebco_08_-30_45_5_65.nc')
# Extract variables
x = dataset.variables['x_range']
y = dataset.variables['y_range']
spacing = dataset.variables['spacing']
# Data limits
nx = (x[-1]-x[0])/spacing[0] # num pts in x-dir
ny = (y[-1]-y[0])/spacing[1] # num pts in y-dir
# Reshape data
zz = dataset.variables['z']
Z = zz[:].reshape(ny, nx)
# setup basemap.
m = Basemap(llcrnrlon=-30,llcrnrlat=45.0,urcrnrlon=5.0,urcrnrlat=65.0,
resolution='i',projection='stere',lon_0=-15.0,lat_0=55.0)
# Set up grid
lons, lats = m.makegrid(nx, ny)
x, y = m(lons, lats)
m.contourf(x, y, flipud(Z))
m.fillcontinents(color='grey')
m.drawparallels(np.arange(10,70,10), labels=[1,0,0,0])
m.drawmeridians(np.arange(-80, 5, 10), labels=[0,0,0,1])
this gives the figure below, clearly not correct. The problem stems from how the areas are defined. For basemap area is defined by lower left corner lat,lon and upper right corner lat, lon. But the gebco data takes a maximum and minimum lon/lat defined along a center line.
Anyone have any experience with gebco data or see a solution??
thanks
D
so just for the record, here's the answer that works, using the comments above:
import netCDF4
from mpl_toolkits.basemap import Basemap
# Load data
dataset = netCDF4.Dataset('/usgs/data1/rsignell/bathy/gebco_08_-30_-45_5_65.nc')
# Extract variables
x = dataset.variables['x_range']
y = dataset.variables['y_range']
spacing = dataset.variables['spacing']
# Compute Lat/Lon
nx = (x[-1]-x[0])/spacing[0] # num pts in x-dir
ny = (y[-1]-y[0])/spacing[1] # num pts in y-dir
lon = np.linspace(x[0],x[-1],nx)
lat = np.linspace(y[0],y[-1],ny)
# Reshape data
zz = dataset.variables['z']
Z = zz[:].reshape(ny, nx)
# setup basemap.
m = Basemap(llcrnrlon=-30,llcrnrlat=45.0,urcrnrlon=5.0,urcrnrlat=65.0,
resolution='i',projection='stere',lon_0=-15.0,lat_0=55.0)
x,y = m(*np.meshgrid(lon,lat))
m.contourf(x, y, flipud(Z));
m.fillcontinents(color='grey');
m.drawparallels(np.arange(10,70,10), labels=[1,0,0,0]);
m.drawmeridians(np.arange(-80, 5, 10), labels=[0,0,0,1]);
which produces this plot.

Categories

Resources