I'm simply trying to plot a map and add the borders of the countries.
Here is the code snipped:
map=Basemap(projection="lcc",resolution="l",width=1E6,height=1E6,lon_0=9.9167,lat_0=51.5167,fix_aspect=False)
map.drawcounties(zorder=1,color="black")
map.shadedrelief()
map.drawcoastlines(color="black",linewidth=2)
map.drawrivers(linewidth=0.5,color="blue")
map.drawmapboundary()
Everything is working besides the borders....There is also no
Error...it simply does nothing.
What am I doing wrong?
Additionaly the resolution of the map is a bit blurred. Is there any way to boost the resolution?
Thanks for your answers!!!
To draw to borders of the countries you need drawcountries. (Mind the r)
To draw to borders of the counties you need drawcounties.
Note however that the german Bundesländer are no "counties" in the sense of the basemap, so it will not draw them.
To get a higher resolution try resolution="i" in the Basemap initialization.
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
map=Basemap(projection="lcc",resolution="i",width=1E6,height=1E6,
lon_0=9.9167,lat_0=51.5167,fix_aspect=False)
map.drawcountries(zorder=1,color="black", linewidth=1)
map.shadedrelief()
map.drawcoastlines(color="black",linewidth=1.2)
map.drawrivers(linewidth=0.5,color="blue")
map.drawmapboundary()
plt.show()
Related
I am using geopandas to draw a map of Italy.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize = (20,30))
region_map.plot(ax=ax, color='white', edgecolor='black')
plt.xlim([6,19])
plt.ylim([36,47.7])
plt.tight_layout()
plt.show()
And this is the results, after properly defining region_map as a piece of 'geometry' GeoSeries .
However, I am unable to modify the figure aspect ratio, even varying figsize in plt.subplots. Am I missing something trivial, or is it likely to be a geopandas issue?
Thanks
Your source dataset (region_map) is obviously "encoded" in geographic coordinate system (units: lats and lons). It is safe to assume in your case this is WGS84 (EPSG: 4326). If you want your plot to look more like it does in e.g Google Maps, you will have to reproject its coordinates into one of many projected coordinate systems (units: meters) . You can use globally acceptable WEB MERCATOR (EPSG: 3857).
Geopandas makes this as easy as possible. You only need to know the basics of how we deal with coordinate projections in computer science and learning most popular CRSes by their EPSG code.
import matplotlib.pyplot as plt
#If your source does not have a crs assigned to it, do it like this:
region_map.crs = {"init": "epsg:4326"}
#Now that Geopandas what is the "encoding" of your coordinates, you can perform any coordinate reprojection
region_map = region_map.to_crs(epsg=3857)
fig, ax = plt.subplots(figsize = (20,30))
region_map.plot(ax=ax, color='white', edgecolor='black')
#Keep in mind that these limits are not longer referring to the source data!
# plt.xlim([6,19])
# plt.ylim([36,47.7])
plt.tight_layout()
plt.show()
I highly recommend reading official GeoPandas docs regarding managing projections.
This seems like it's going to be something simple that will fix my code but I think I've just looked at the code too much at the moment and need to get some fresh eyes on it. I'm simply trying to bring in a Grib2 file that I've downloaded from NCEP for the HRRR model. According to their information the grid type is Lambert Conformal with the extents of (21.13812, 21.14055, 47.84219, 47.83862) for the latitudes of the corners and (-122.7195, -72.28972, -60.91719, -134.0955) for the longitudes of the corners for the models domain.
Before even trying to zoom into my area of interest I just wanted to simply display an image in the appropriate CRS however when I try to do this for the domain of the model I get the borders and coastlines to fall within that extent but the actual image produced from the Grib2 file is just zoomed into. I've tried to use extent=[my domain extent] but it always seems to crash the notebook I'm testing it in. Here is my code and the associated image that I get from it.
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy
from mpl_toolkits.basemap import Basemap
from osgeo import gdal
gdal.SetConfigOption('GRIB_NORMALIZE_UNITS', 'NO')
plt.figure()
filename='C:\\Users\\Public\\Documents\\GRIB\\hrrr.t18z.wrfsfcf00.grib2'
grib = gdal.Open(filename, gdal.GA_ReadOnly)
z00 = grib.GetRasterBand(47)
meta00 = z00.GetMetadata()
band_description = z00.GetDescription()
bz00 = z00.ReadAsArray()
latitude_south = 21.13812 #38.5
latitude_north = 47.84219 #50
longitude_west = -134.0955 #-91
longitude_east = -60.91719 #-69
fig = plt.figure(figsize=(20, 20))
title= meta00['GRIB_COMMENT']+' at '+meta00['GRIB_SHORT_NAME']
fig.set_facecolor('white')
ax = plt.axes(projection=ccrs.LambertConformal())
ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
ax.coastlines(resolution='110m')
ax.imshow(bz00,origin='upper',transform=ccrs.LambertConformal())
plt.title(title)
plt.show()
Returns Just Grib File
If I change:
ax = plt.axes(projection=ccrs.LambertConformal()
to
ax = plt.axes(projection=ccrs.LambertConformal(central_longitude=-95.5,
central_latitude=38.5,cutoff=21.13)
I get my borders but my actual data is not aligned and it creates what I'm dubbing a Batman plot.
Batman Plot
A similar issue occurs even when I do zoom into the domain and still have my borders present. The underlying data from the Grib file doesn't change to correspond to what I'm trying to get.
So as I've already said this is probably something that is an easy fix that I'm just missing but if not, it would be nice to know what step or what process I'm screwing up that I can learn from so that I don't do it in the future!
Updated 1:
I've added and changed some code and am back to getting only the image to show without the borders and coastlines showing up.
test_extent = [longitude_west,longitude_east,latitude_south,latitude_north]
ax.imshow(bz00,origin='upper',extent=test_extent)
This gives me the following image.
Looks exactly like image 1.
The other thing that I'm noticing which maybe the root cause of all of this is that when I'm printing out the value for plt.gca().get_ylim() and plt.gca().get_xlim() I'm getting hugely different values depending on what is being displayed.
It seems that my problem arises from the fact that the Grib file regardless of whether or not it can be displayed properly in other programs just doesn't play nicely with Matplotlib and Cartopy out of the box. Or at the very least does not with the Grib files that I was using. Which for sake of this perhaps helping others in the future are from the NCEP HRRR model that you can get here or here.
Everything seems to work nicely if you convert the file from Grib2 format to NetCDF format and I was able to get what I wanted with the borders, coastlines, etc. on the map. I've attached the code and the output below to show how it worked. Also I hand picked a single dataset that I wanted to display to test versus my previous code so incase you want to look at the rest of datasets available in the file you'll need to utilize ncdump or something similar to view the information on the datasets.
import numpy as np
from netCDF4 import Dataset
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy
import cartopy.feature as cfeature
from osgeo import gdal
gdal.SetConfigOption('GRIB_NORMALIZE_UNITS', 'NO')
nc_f = 'C:\\Users\\Public\\Documents\\GRIB\\test.nc' # Your filename
nc_fid = Dataset(nc_f, 'r') # Dataset is the class behavior to open the
# file and create an instance of the ncCDF4
# class
# Extract data from NetCDF file
lats = nc_fid.variables['gridlat_0'][:]
lons = nc_fid.variables['gridlon_0'][:]
temp = nc_fid.variables['TMP_P0_L1_GLC0'][:]
fig = plt.figure(figsize=(20, 20))
states_provinces = cfeature.NaturalEarthFeature(category='cultural', \
name='admin_1_states_provinces_lines',scale='50m', facecolor='none')
proj = ccrs.LambertConformal()
ax = plt.axes(projection=proj)
plt.pcolormesh(lons, lats, temp, transform=ccrs.PlateCarree(),
cmap='RdYlBu_r', zorder=1)
ax.add_feature(cartopy.feature.BORDERS, linestyle=':', zorder=2)
ax.add_feature(states_provinces, edgecolor='black')
ax.coastlines()
plt.show()
Final Preview of Map
I'm trying to animate a heat map of some information regarding geographic locations in Pittsburgh using matplotlib and basemap in Python 3. Right now I'm having issues getting basemap to use ARCGis imagery as the background. The following code only produces a blue square
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
m =Basemap(llcrnrlon=40.361369,llcrnrlat=-80.0955278,
urcrnrlon=40.501368,urcrnrlat=-79.865723,epsg=2272)
m.arcgisimage(service='ESRI_StreetMap_World_2D', xpixels=7000,dpi=96,verbose=True)
I've pulled down and run several examples from the internet about how to use arcgis images with basemap and they have run so I'm pretty sure its not a connection issue. I've tried several different projections and EPSG's including the world and US EPSGs, but no luck. Any help would be appreciated.
You have the longitudes and latitudes mixed up (see here):
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
m = Basemap(
llcrnrlat=40.361369, llcrnrlon=-80.0955278,
urcrnrlat=40.501368, urcrnrlon=-79.865723,
epsg = 2272
)
m.arcgisimage(service='ESRI_StreetMap_World_2D', xpixels=7000, verbose=True)
plt.show()
produces this image:
I'm trying to do a correlation plot using python, so I'm starting with this basic example
import numpy as np
import matplotlib.pyplot as plt
image=np.random.rand(10,10)
plt.imshow(image)
plt.colorbar()
plt.show()
ok, this script give to me an image like this
so the next step is to put my dataset and not a random matrix, i know it, but I want to put some axis or text in this plot, and to get something like this image
It is a very pretty image using paint (lol), but someone can say me what way I need to follow to do something like thik please (how to search it in google).
Before to post it I think in labels, but also I think that I can assign only one label to each axis
cheers
As #tcaswell said in the comments, the function you want to use is annotate, and the documentation can be found here.
I've given an example below using your code above:
import numpy as np
import matplotlib.pyplot as plt
def annotate_axes(x1,y1,x2,y2,x3,y3,text):
ax.annotate('', xy=(x1, y1),xytext=(x2,y2), #draws an arrow from one set of coordinates to the other
arrowprops=dict(arrowstyle='<->'), #sets style of arrow
annotation_clip=False) #This enables the arrow to be outside of the plot
ax.annotate(text,xy=(0,0),xytext=(x3,y3), #Adds another annotation for the text
annotation_clip=False)
fig, ax = plt.subplots()
image=np.random.rand(10,10)
plt.imshow(image)
plt.colorbar()
#annotate x-axis
annotate_axes(-0.5,10,4.5,10,2.5,10.5,'A') # changing these changes the position of the arrow and the text
annotate_axes(5,10,9.5,10,7.5,10.5,'B')
#annotate y-axis
annotate_axes(-1,0,-1,4,-1.5,2,'A')
annotate_axes(-1,4.5,-1,9.5,-1.5,7.5,'B')
plt.show()
This give the image shown below:
I would like to create a pdf file [by using plt.savefig("~~~.pdf")]
containing lots of (about 20) subplots
each of which is drawing timeseries data.
I am using a matplotlib library with python language.
Each subplot may be long, and I want to put the subplots
horizontally.
Therefore, the figure should be very long (horizontally), so the horizontal scroll bar should be needed!
Is there any way to do this?
some example code will be appreciated!
The following is my sample code.
I just wanted to draw 10 sine graphs arranged horizontally
and save it as pdf file.
(but I'm not pretty good at this. so the code may looks to be weird to you.. :( )
from matplotlib import pyplot as plt
import numpy as np
x=np.linspace(0,100,1000)
y=np.sin(x)
numplots=10
nr=1
nc=numplots
size_x=nc*50
size_y=size_x*3/4
fig=plt.figure(1,figsize=(size_x,size_y))
for i in range(nc):
ctr=i+1
ax=fig.add_subplot(nr,nc,ctr)
ax.plot(x,y)
plt.savefig("longplot.pdf")
plt.clf()
Thank you!
You should do that using the backend "matplotlib.backends.backend_pdf". This enables you to save matplotlib graphs in pdf format.
I have simplified your code a bit, here is a working example:
from matplotlib import pyplot as plt
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
x = np.linspace(0,100,1000)
y = np.sin(x)
nr = 10
nc = 1
for i in range(nr):
plt.subplot(nr, nc, i + 1)
plt.plot(x, y)
pdf = PdfPages('longplot.pdf')
pdf.savefig()
pdf.close()
I hope this helps.
In the link below there is a solution, which can help you, since it was helpful to me either.
Scrollbar on Matplotlib showing page
But if you have many subplots, I am afraid your problem won't be solved. Since it will shrink each graph anyway. In that case it will be better to break your graphs into smaller and separate parts.