I am in trouble with how to plot the coordinate given in a file.csv using basemap. It has error when I run with latlon=True. My code below :
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
df=pd.read_csv('E:\Classification\DATA.csv')
lat=df['Latitude']
lon=df['Longitude']
plt.figure(figsize=(12,7))
m = Basemap(projection='mill',
llcrnrlat = 7,
urcrnrlat = 25,
llcrnrlon = 90,
urcrnrlon = 120,
resolution = 'l')
m.drawcoastlines()
m.drawcountries()
m.drawstates()
m.fillcontinents(color='None',lake_color='#FFFFFF')
m.drawmapboundary(color='k', linewidth=1.0, fill_color=None, zorder=None, ax=None)
parallels = np.arange(0.,81,10.)
# labels = [left,right,top,bottom]
m.drawparallels(parallels,labels=[False,True,True,False])
meridians = np.arange(10.,351.,5.)
m.drawmeridians(meridians,labels=[True,False,False,True])
m.scatter(lon,lat,latlon=True,c='red', marker='o',linewidth=1, zorder=2)
plt.show()
I really appreciate if some of you can help me. Thank you so much.
Try using lon.values, lat.values in place of lon, lat in m.scatter().
m.scatter(lon.values, lat.values, latlon=True,c='red', marker='o',linewidth=1, zorder=2)
Related
I need to plot some data in Germany with cartopy. The data part of my plot works fine (so I deleted it for now). Unfortunately, the shape of the country is deformed due to the projection.
I am currently using the PlateCarree projection, but changing it to Orthographic or others created the same plot.
How to improve the shape?
Code:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.io import shapereader
# get country borders
resolution = '10m'
category = 'cultural'
name = 'admin_0_countries'
shpfilename = shapereader.natural_earth(resolution, category, name)
df = geopandas.read_file(shpfilename)
poly = df.loc[df['ADMIN'] == 'Germany']['geometry'].values[0]
# plot
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_extent([5.8, 15.1, 47.25, 55.1],
crs=ccrs.PlateCarree())
ax.add_geometries(poly,
crs=ccrs.PlateCarree(),
facecolor='gainsboro',
edgecolor='slategray',
lw=0.1,
alpha=.8)
# save plot
save_path = 'germany.png'
plt.savefig(save_path, dpi=250, bbox_inches='tight', pad_inches=0.)
plt.close()
The solution is transforming the Geopandas Dataframe using the same projection as explained here
New output:
germany.png
New code:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import geopandas
from cartopy.io import shapereader
# get country borders
resolution = "10m"
category = "cultural"
name = "admin_0_countries"
shpfilename = shapereader.natural_earth(resolution, category, name)
df = geopandas.read_file(shpfilename)
df_de = df.loc[df["ADMIN"] == "Germany"]
extent = [6., 14.8, 47.1, 55.1]
# plot
crs = ccrs.Orthographic(
central_longitude=(0.5 * (extent[0] + extent[1])),
central_latitude=(0.5 * (extent[2] + extent[3])),
)
crs_proj4 = crs.proj4_init
df_de.crs = "EPSG:4326"
df_ae = df_de.to_crs(crs_proj4)
fig, ax = plt.subplots(subplot_kw={"projection": crs})
ax.set_extent(extent)
ax.add_geometries(
df_ae["geometry"],
crs=crs,
facecolor="gainsboro",
edgecolor="slategray",
lw=0.1,
alpha=0.8,
)
# save plot
save_path = "germany.png"
plt.savefig(save_path, dpi=250, bbox_inches="tight", pad_inches=0.0)
plt.close()
I'm still very new to programming and trying to create a contour plot of alkalinity across Hawaii using Cartopy. I will need to interpolate the point values called MODIFIED_TA against an x-y mesh grid but have not been able to figure out how to do this. The code I'm using is:
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import cartopy.crs as ccrs
import cartopy.mpl.ticker as cticker
import statistics
from scipy.interpolate import UnivariateSpline
import numpy as np
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import warnings
warnings.filterwarnings("ignore") # ignoring the warning prompts.
%matplotlib inline
fig = plt.figure(figsize=(15,15))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree(central_longitude=-170))
landgreen = cfeature.NaturalEarthFeature('physical', 'land', '110m',
edgecolor='face', facecolor='green')
oceanaqua = cfeature.NaturalEarthFeature('physical', 'ocean', '110m',
edgecolor='face', facecolor='aqua')
ax.set_extent([-151.5, -162, 18, 24], ccrs.PlateCarree())
ax.set_title('TOTAL ALKALINITY')
ax.add_feature(landgreen)
ax.add_feature(cfeature.OCEAN, color = 'k')
ax.gridlines(draw_labels=True)
lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
ax.grid(linewidth=2, color='black', alpha=0.5, linestyle='--')
lons = all_data.LONGITUDE[:]
lats = all_data.LATITUDE[:]
alk = all_data.MODIFIED_TA[:]
x1,y1 = np.meshgrid(lons,lats)
z1,z2 = np.meshgrid(all_data.MODIFIED_TA,all_data.MODIFIED_TA)
plt.tricontourf(lons,lats,alk, transform=ccrs.PlateCarree(), cmap=cm.gist_rainbow)
plt.colorbar(shrink=0.5)
plt.title('$A_{T}$ VALUES', color = 'k', fontname='Times New Roman',size = 23)
plt.plot()
The result is nothing like what I was hoping for and again, I'm not sure how to interpolate this value so that it comes out as a smooth gradient across the x/y coordinate grid. Any help would be greatly appreciated!
See output here
It's hard to tell for sure without being able to see your data. I tried to create a MRE and it worked. I would start by seeing if this works.
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.mpl.ticker as cticker
import numpy as np
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree(central_longitude=-170))
ax.set_extent([-151.5, -162, 18, 24], ccrs.PlateCarree())
ax.add_feature(cfeature.OCEAN)
ax.gridlines(draw_labels=True)
lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
ax.grid(linewidth=2, color='black', alpha=0.5, linestyle='--')
lons = np.random.random(80) * 7 - 160
lats = np.random.random(80) * 4 + 19
alk = np.cos(lons * 10 * np.pi / 180) * np.sin(lats * 20 / 180)
plt.plot(lons, lats, 'k.', transform = ccrs.PlateCarree())
plt.tricontourf(lons,lats,alk, transform=ccrs.PlateCarree(), alpha = 0.5)
plt.colorbar(shrink=0.5)
plt.title('$A_{T}$ VALUES', color = 'k', fontname='Times New Roman',size = 23)
If it does work, then what I'd look at would include:
What are the dimensions of all_data.LONGITUDE, all_data.LATITUDE, all_data.MOTIFIED_TA?
Are there duplicate values?
Does it work when you plot it outside of a projection?
If my example does not work, then it suggests there is something about your install, in which case update it if you can. If the problem still persists, perhaps there is a bug cartopy that needs reporting or a conflict with other packages.
Sorry, I cannot help further.
I am trying to copy the method that was done on this page: https://makersportal.com/blog/2018/7/20/geographic-mapping-from-a-csv-file-using-python-and-basemap under "Mapping Interesting Data" to have a color bar associated with my data.
Right now I just get a plain map of South America, which is what I want as my background but there is no data included.
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
m = Basemap(projection='mill',
llcrnrlat = -30, #bottom
llcrnrlon = -120, #left
urcrnrlat = 20, #top
urcrnrlon = -50, #right
resolution='c')
m.drawcoastlines()
m.drawcountries()
# format colors for elevation range
SST_min = np.min(df5.DaasgardSST)
SST_max = np.max(df5.DaasgardSST)
cmap = plt.get_cmap('gist_earth')
normalize = matplotlib.colors.Normalize(vmin=SST_min, vmax=SST_max)
# plot SST with different colors
for i in range(0,len(df5.DaasgardSST)):
x,y = m(lon,lat)
color_interp = np.interp(df5,[SST_min,SST_max],[0,30])
plt.plot(x,y,marker='o',markersize=6,color=cmap(int(color_interp)))
# format the colorbar
cax, _ = matplotlib.colorbar.make_axes(ax)
cbar = matplotlib.colorbar.ColorbarBase(cax, cmap=cmap,norm=normalize,label='Elevation')
plt.title('Title')
plt.show()
I made heat map on basemap like this and evrything work well, but i want to add else label with number of occurrences, and i get: RuntimeError: No mappable was found to use for colorbar creation. First define a mappable such as an image (with imshow) or a contour set (with contourf).
How to do it correctly ?
import numpy as np
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
import pandas as pd
df = pd.read_csv(r"C:\Users\Piotr\Desktop\Meteorite_Landings1.csv")
df = df.dropna()
lat = df['reclat'].values
lon = df['reclong'].values
m = Basemap(projection = 'mill',
llcrnrlat = -90,
urcrnrlat = 90,
llcrnrlon = -180,
urcrnrlon = 180,
resolution = 'c')
m.drawparallels(np.arange(-90, 90,10), labels=[True, False, False, False])
m.drawmeridians(np.arange(-180, 180, 30), labels = [0,0,0,1])
m.drawcoastlines()
x,y = m(lon, lat)
m.plot(x, y, 'o', c= range(amount), markersize=4,zorder=8, markerfacecolor='#424FA4',markeredgecolor="none", alpha=0.33)
plt.colorbar(label="Amount")
plt.clim(0, 6000)
plt.show()
You need to do some statistic computing that produces mappable values for the colorbar. For example, replace the line:
m.plot(...)
with
m.hexbin(x, y, bins='log', gridsize=30, alpha=0.5, edgecolors='gray')
It will show the number of occurrences better than using heatmap.
If you want to take the mass into consideration, you can use:
m.hexbin(x,y, bins='log', C=df['mass_g'].values, gridsize=30, alpha=0.5, edgecolors='gray')
You will get an output plot like this:
Hope this helps.
I am trying to plot some bathymetry data using cartopy. I slice out a section of the data and plot it over a Mercator projection. It produces a map that looks ok but I get the following error,
IllegalArgumentException: Invalid number of points in LinearRing found 3 - must be 0 or >= 4
Shell is not a LinearRing
Should I be worried about this? My code is below,
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['contour.negative_linestyle'] = 'solid'
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import cartopy.feature as cfeature
from netCDF4 import Dataset
# load data and slice out region of interest
_file = 'GEBCO_2014_2D.nc'
gebco = Dataset(_file, mode='r')
g_lons = gebco.variables['lon'][:]
g_lon_inds = np.where((g_lons>=-30) & (g_lons<=10))[0]
g_lons = g_lons[g_lon_inds]
g_lats = gebco.variables['lat'][:]
g_lat_inds = np.where((g_lats>=40) & (g_lats<=65))[0]
g_lats = g_lats[g_lat_inds]
d = gebco.variables['elevation'][g_lat_inds, g_lon_inds]
gebco.close()
# plot data
projection=ccrs.Mercator()
extent = [-30, 10, 40, 65]
fig = plt.figure(figsize=(13.3, 10))
ax = fig.add_subplot(111, projection=projection)
lon_labels = np.arange(-30, 20, 10)
lat_labels = np.arange(40, 75, 10)
gl = ax.gridlines(draw_labels=True, xlocs=lon_labels, ylocs=lat_labels)
gl.xlabels_top = gl.ylabels_right = False
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
ax.set_extent(extent, crs=ccrs.PlateCarree())
coastline_10m = cfeature.NaturalEarthFeature('physical', 'coastline', '10m',
edgecolor='k', alpha=0.6,
facecolor=cfeature.COLORS['land'])
ax.add_feature(coastline_10m)
CS = plt.contour(g_lons, g_lats, d, [-1000,-150],
colors='k', alpha=0.4, linewidth=0.5, zorder=1,
transform=ccrs.PlateCarree())
plt.clabel(CS, inline=True, fontsize=10, fmt='%i')