how to display netcdf raster values over map? - numpy

I'm trying to plot netcdf raster values of snowfall data in a text format overlaying what I currently have (mentioned further below). Example, something like this below:
Example
This is all the relevant code I have so far. I excluded the non relevant code. I tried plt.text and it gave me "ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"
What I have plotted so far
import numpy
from datetime import datetime
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cartopy.mpl.ticker as cticker
import matplotlib.pyplot as plt
from matplotlib import ticker, patheffects
from metpy.units import units
import numpy as np
import numpy.ma as ma
from scipy.ndimage import gaussian_filter, maximum_filter, minimum_filter
import xarray as xr
from metpy.plots import USCOUNTIES
from gradient import Gradient
import pandas as pd
import matplotlib.colors as col
#Open NOAA Snowfall dataset
ds = xr.open_dataset('sfav2_CONUS_2021093012_to_2022042512.nc')
ds
lat = ds.lat
lon = ds.lon
#converts snowfall data to inches
snowdata = ds['Data'] * 39
plt.text(lon, lat, snowdata, transform=datacrs)

As far as I know there isn't a vectorized way of plotting text (plt.text or plt.annotated). So you'll have to loop over the arrays and plot each point.
import matplotlib.pyplot as plt
import matplotlib.patheffects as PathEffects
import cartopy.crs as ccrs
import numpy as np
data = np.random.rand(18, 9)
lons, lats = np.mgrid[-17:18:2, 8:-9:-2]
lons = lons * 10
lats = lats * 10
fig, ax = plt.subplots(figsize=(10, 5), dpi=86, facecolor="w", subplot_kw=dict(projection=ccrs.EqualEarth()))
ax.pcolormesh(lons, lats, data, cmap="coolwarm", alpha=.2, transform=ccrs.PlateCarree())
ax.coastlines()
for val, lat, lon in zip(data.flat, lats.flat, lons.flat):
ax.text(
lon, lat, f"{val:1.1f}", ha="center", va="center", transform=ccrs.PlateCarree(),
path_effects=[PathEffects.withStroke(linewidth=3, foreground="w", alpha=.5)],
)

Related

How to show the peaks of pmf by matplotlib and scipy?

this is the code(I want to know the peak of the picture but I don't know how to add this kind of code)
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
from scipy import stats
n=25
p=0.6
k=np.arange(0,50)
#the pmf forming
picture=stats.binom.pmf(k,n,p)
print(picture)
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
mean,var,skew,kurt=stats.binom.stats(n,p,moments='mvsk')
print(mean,var,skew,kurt)
#the picture forming
plt.plot(k,picture,'o-')
plt.grid(True)
plt.show()
You can use scatter
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
from scipy import stats
n=25
p=0.6
k=np.arange(0,50)
#the pmf forming
picture=stats.binom.pmf(k,n,p)
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
mean,var,skew,kurt=stats.binom.stats(n,p,moments='mvsk')
print(mean,var,skew,kurt)
#the picture forming
plt.plot(k,picture,'o-')
plt.grid(True)
# the two new lines
max_ind = np.argmax(picture)
plt.scatter(x=k[max_ind],y=picture[max_ind],c='r',s=100,zorder=10)
and this produces

seaborn.swarmplot problem with symlog scale: zero's are not expanded

I have a data set of positive values and zero's that I would like to show on the log scale. To represent zero's I use 'symlog' option, but all zero values are mapped into one point on swarmplot. How to fix it?
import numpy as np
import seaborn as sns
import pandas as pd
import random
import matplotlib.pyplot as plt
n = 100
x = np.concatenate(([0]*n,np.linspace(0,1,n),[5]*n,np.linspace(10,100,n),np.linspace(100,1000,n)),axis=None)
data = pd.DataFrame({'value': x, 'category': random.choices([0,1,2,3], k=len(x))})
f, ax = plt.subplots(figsize=(10, 6))
ax.set_yscale("symlog",linthreshy=1.e-2)
ax.set_ylim(ymax=1000)
sns.swarmplot(x="category", y="value", data=data)
sns.despine(left=True)
link to the resulting plot

controlling the number of x ticks in pyplot

I want to display all 13 x ticks, but the graph only shows 7 of them having two intervals.
plt.locator_params(axis='x',nbins=13)
Why doesn't above code work??
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.dates as dates
y = [0, 0.86, 0.826, 0.816, 0.807, 0.803, 0.804, 0.803, 0.802,0.81, 0.813, 0.813, 0.813]
times = pd.date_range('2015-02-25', periods=13)
fig, ax = plt.subplots(1)
fig.autofmt_xdate()
xfmt = dates.DateFormatter('%d-%m-%y')
ax.xaxis.set_major_formatter(xfmt)
plt.locator_params(axis='x',nbins=13)
ax.plot_date(times.to_pydatetime(), y, 'v-')
ax.xaxis.set_minor_locator(dates.WeekdayLocator(byweekday=(1),
interval=1))
ax.xaxis.set_minor_formatter(dates.DateFormatter('%d\n%a'))
ax.xaxis.grid(True, which="minor")
ax.yaxis.grid()
plt.tight_layout()
plt.show()
The warning should give you some clue why this is happening:
UserWarning: 'set_params()' not defined for locator of type <class 'pandas.tseries.converter.PandasAutoDateLocator'>
str(type(self)))
Use plt.xticks(times.to_pydatetime()) instead:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.dates as dates
y = [0, 0.86, 0.826, 0.816, 0.807, 0.803, 0.804, 0.803, 0.802,0.81, 0.813, 0.813, 0.813]
times = pd.date_range('2015-02-25', periods=13)
fig, ax = plt.subplots(1)
fig.autofmt_xdate()
xfmt = dates.DateFormatter('%d-%m-%y')
ax.xaxis.set_major_formatter(xfmt)
ax.plot_date(times.to_pydatetime(), y, 'v-')
ax.xaxis.set_minor_locator(dates.WeekdayLocator(byweekday=(1),
interval=1))
plt.xticks(times.to_pydatetime())
ax.xaxis.set_minor_formatter(dates.DateFormatter('%d\n%a'))
ax.xaxis.grid(True, which="minor")
ax.yaxis.grid()
plt.tight_layout()
plt.show()

name "plot" is not defined

I'm trying to plot some data using matplotlib with the code below.
import matplotlib.pyplot as plt
import numpy as np
data_x = np.linspace(0, 10, 100)
data_y = 10 * np.exp(-data_x)
np.savetxt('tabelle1.txt', np.column_stack([data_x, data_y]), header='U I')
x, y = np.genfromtxt('tabelle1', unpack=True)
plt.plot(x, y, 'rx')
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')
plt.yscale('log')
plt.tight_layout()
plt.savefig('loesung.pdf')
However, this generates an error saying NameError: name plot is not defined.
How can I fix this?
please try
#Add this script
import matplotlib
#Before
import matplotlib.pyplot as plt

Map offsite with matplotlib(using geopandas and cartopy)

I have created a map like this:
The problem with it is that on the right side of the map is always a little bit offsite. I have set the bounds to:
ax.set_xlim(-215800,
1000000)
ax.set_ylim(3402659,
4879248)
No matter how I increase the xlim, or set margin the right side is still outside the bounds of the canvas. Can somebody help?
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from osgeo import ogr
import matplotlib.pyplot as plt
import matplotlib as mpl
import rasterio
import cartopy.crs as ccrs
import geopandas
from geopandas import *
from matplotlib import colors
MediumApple='#55FF00'
Cantaloupe='#FFA77F'
Marsred='#FF0000'
crs = ccrs.UTM(zone=10)
ax = plt.axes(projection=crs)
import matplotlib.patches as mpatches
for county in CAcountylist:
with rasterio.drivers():
with rasterio.open(r"CA\%s \%s.tif"%(county,county),"r") as src:
meta = src.meta
im=src.read().astype('f')
im=np.transpose(im,[1,2,0])
print im.shape
print im.min(),im.max()
im[im==0]=np.nan
im=im.squeeze()
xmin = src.transform[0]
xmax = src.transform[0] + src.transform[1]*src.width
print src.width,src.height
ymin = src.transform[3] + src.transform[5]*src.height
ymax = src.transform[3]
colors=[MediumApple,Cantaloupe,Marsred]
cmap=mpl.colors.ListedColormap([MediumApple,Cantaloupe,Marsred])
bounds_color=[1,1,2,2,3,3]
norm=mpl.colors.BoundaryNorm(bounds_color,cmap.N)
print xmin,xmax,ymin,ymax
ax.imshow(im, origin='upper', extent=[xmin,xmax,ymin,ymax], transform=crs, interpolation='nearest',cmap=cmap,norm=norm)
df=GeoDataFrame.from_file(r"\CACounty.shp")
df=df.to_crs(epsg=26910)
df.plot(axes=ax,alpha=0)
bounds = df.geometry.bounds
ax.set_xlim(-215800,
1000000)
ax.set_ylim(3402659,
4879248)
low_patch = mpatches.Patch(color='#55FF00', label='Low')
Moderate_patch = mpatches.Patch(color='#FFA77F', label='Moderate')
High_patch = mpatches.Patch(color='#FF0000', label='High')
plt.legend(handles=[low_patch,Moderate_patch,High_patch],loc=3)
plt.show()