I am using WRF output data to plot SkweT, here is code:
import wrf
from netCDF4 import Dataset
import matplotlib.pyplot as plt
import numpy as np
import metpy.calc as mpcalc
from metpy.plots import SkewT
from metpy.units import units
wrfin = Dataset(r'wrfout_d02_2022-06-19_00_00_00')
lat_lon = [25.0803, 121.2183]
x_y = wrf.ll_to_xy(wrfin, lat_lon[0], lat_lon[1])
p1 = wrf.getvar(wrfin,"pressure",timeidx=0)
T1 = wrf.getvar(wrfin,"tc",timeidx=0)
Td1 = wrf.getvar(wrfin,"td",timeidx=0)
u1 = wrf.getvar(wrfin,"ua",timeidx=0)
v1 = wrf.getvar(wrfin,"va",timeidx=0)
p = p1[:,x_y[0],x_y[1]] * units.hPa
T = T1[:,x_y[0],x_y[1]] * units.degC
Td = Td1[:,x_y[0],x_y[1]] * units.degC
u = v1[:,x_y[0],x_y[1]] * units('m/s')
v = u1[:,x_y[0],x_y[1]] * units('m/s')
skew = SkewT()
skew.plot(p, T, 'r')
skew.plot(p, Td, 'g')
my_interval = np.arange(100, 1000, 50) * units('mbar')
ix = mpcalc.resample_nn_1d(p, my_interval)
skew.plot_barbs(p[ix], u[ix], v[ix])
skew.plot_dry_adiabats()
skew.plot_moist_adiabats()
skew.plot_mixing_lines()
skew.ax.set_ylim(1000, 100)
skew.ax.set_xlim(-60, 40)
skew.ax.set_xlabel('Temperature ($^\circ$C)')
skew.ax.set_ylabel('Pressure (hPa)')
plt.savefig('SkewT.png', bbox_inches='tight')
but running error message especially in the block:
**raise DimensionalityError(
pint.errors.DimensionalityError: Cannot convert from 'dimensionless' (dimensionless) to 'millibar' ([mass] / [length] / [time] ** 2)**
It seems that mpcalc.resample_nn_1d doesn't work.
how can I solve it?
python version : 3.9.7
metpy version : 0.12.0
My guess is that wrf.getvar() is returning NumPy masked arrays, which behave a little weird with the Pint Quantity instances (compared with normal arrays). I would recommend trying this syntax to "attach" units:
p = units.Quantity(p1[:,x_y[0],x_y[1]], 'hPa')
T = units.Quantity(T1[:,x_y[0],x_y[1]], 'degC')
Td = units.Quantity(Td1[:,x_y[0],x_y[1]], 'degC')
u = units.Quantity(v1[:,x_y[0],x_y[1]], 'm/s')
v = units.Quantity(u1[:,x_y[0],x_y[1]], 'm/s')
Also, a heads up that MetPy 0.12 is quite a bit out of date, and I would recommend updating to the latest version (currently 1.3.1) as soon as you can.
Related
I am using Mac OS Monterey, I am tying to run a python code and get two graphs as output, but not getting any. I have ran the code in both atom and Jupiter notebooks and code is running fine without any errors, but I am still not getting any output.
import glob
from astropy.coordinates import get_icrs_coordinates
from astropy.coordinates import SkyCoord
from astropy.io import fits
import astropy.units as u
import matplotlib as mpl
import numpy as np
import pylab as pl
project_Coords = get_icrs_coordinates('4FGL J1256.9+2736')
ra0=project_Coords.ra.value
dec0=project_Coords.dec.value
def load_event_data():
f = fits.open('project_merged.fits')
ra = f['events'].data.field('ra')
dec = f['events'].data.field('dec')
en = f['events'].data.field('energy')
#ph = f['events'].data.field('pulse_phase')
ph = None
f.close()
return ra,dec,en,ph
def make_counts_map():
ra,dec,en,ph = load_event_data()
mask = en>1000
c = SkyCoord(ra[mask]*u.deg,dec[mask]*u.deg,frame = 'icrs')
c0 = SkyCoord(ra0*u.deg,dec0*u.deg)
gal = c.galactic
gal_b = gal.b.value
gal_l = gal.l.value
b0 = c0.galactic.b.value
l0 = c0.galactic.l.value
l_bins = np.linespace(l0-20,l0+20,41)
b_bins = np.linespace(b0-20,b0+20,41)
#Plot sky map
pl.figure(1); pl.clf()
pl.hist2d(gal_l,gal_b,bins [l_bins,b_bins] , norm=mpl.colors.LogNorm() ,vmin=2e2,vmax=1e4);
pl.xlabel('Galactic Longitude')
pl.ylable('Galactic Latitude')
pl.colorbar()
plt.show()
#plot longitude slice around b= -3
pl.figure(2); pl.clf()
mask = np.abs(gal_b - (-3.15)) < 0.5
pl.gca().set_yselect('log')
l_bins = np.linspace(l0-20,l0+20,101)
pl.hist(gal_l[mask],bins=l_bins)
pl.xlabel('A')
pl.ylable('B')
I'd like to reproduce Python code to R code about Stick-breaking process, which is one of construction schemes for Dirichlet Process. However, the plot I drew within R is quite different in that DP sample distributions are not around the base distribution, H.
The reference Python code is from Austin Rochford's blog.
from matplotlib import pyplot as plt
import numpy as np
import pymc3 as pm
import scipy.stats as ss
import seaborn as sns
from statsmodels.datasets import get_rdataset
from theano import tensor as T
np.random.seed(433)
N=20
K=30
alpha=50
H = ss.norm # base dist
beta = ss.beta.rvs(1,alpha, size=(N,K))
pi = np.empty_like(beta)
pi[:, 0] = beta[:,0]
pi[:, 1:] = beta[:, 1:] * (1-beta[:, :-1]).cumprod(axis=1)
omega = H.rvs(size=(N,K))
x_plot = np.linspace(-3,3,200)
sample_cdfs = (pi[..., np.newaxis]* np.less.outer(omega, x_plot)).sum(axis=1)
fig, ax = plt.subplots(figsize=(8,6))
ax.plot (x_plot, sample_cdfs[0],c="gray", alpha=0.75, label = "DP sample CDFs")
ax.plot(x_plot, sample_cdfs[1:].T, c="gray", alpha=0.75)
ax.plot(x_plot, H.cdf(x_plot), c= "k", label = "Base CDF")
ax.set_title(r'$\alpha = {}$'.format(alpha))
ax.legend(loc=2)
The figure on the right side is the result in Python code.
And I tried to convert it to R code:
library(yarrr)
N=20;K=30;ngrid=200;alpha=50
xgrid = seq(-3,3,length.out=ngrid)
betas = matrix(rbeta(N*K, 1, alpha),nr=N, nc=K)
stick.to.right = c(1, cumprod(1 - betas))[1:K]
pis.temp = stick.to.right * betas
omega = matrix(rnorm(N*K),nr=N,nc=K)
dirac = array(numeric(N*K*ngrid),dim=c(N,K,ngrid))
for(i in 1:N){
for(j in 1:K){
for(k in 1:ngrid){
dirac[i,j,k]=ifelse(omega[i,j]<xgrid[k],TRUE,FALSE)
}
}
}
pis = array(pis.temp,dim=c(N,K,200))
sample_cdfs = apply(pis* dirac,c(1,3),sum)
plot(xgrid,sample_cdfs[1,],col=piratepal("pony"),type="l",lwd=1,ylim=c(0,1))
for(i in 2:N) lines(xgrid,sample_cdfs[i,],col=piratepal("pony")[i])
lines(xgrid,pnorm(xgrid),lwd=2)
The plot I drew is DP with alpha=50:
How can I modify R code to give a similar result as Python code?
I'm writing a program that obtains plot data from a graph(JPEG).
Vertical axis is logarithmic.
I successfully made a program that understands horizontal and vertical axes as linear (not logarithmic), see the code below:
%matplotlib inline
from PIL import Image
from scipy import *
from pylab import *
im = array(Image.open('fig1.jpg'))
hh = im.shape[0]
ww = im.shape[2]
imshow(im)
print(im[100,0,:])
Col = array([255,0,0])#赤
bnd = 30
yax = linspace(0.5,2e-4,hh)
xax = linspace(1,14,ww)
for i in range(hh):
for j in range(ww):
im[i,j,:] = 255*(any(im[i,j,:]>Col+bnd) or any(im[i,j,:]<Col-bnd))
mapim = abs(im[:,:,0]/255-1).astype(bool)
yval = array([average(yax[mapim[:,t]]) for t in range(ww)])
rlt = interp(range(100),xax,yval)
I have no idea how to modify it to make it understand logarithmic axis.
Please help me.
You just need to convert the y max and min to log scale:
ymax_lin = log10(0.5)
ymin_lin = log10(2e-4)
yax = linspace(ymax_lin,ymin_lin,hh)
and convert back to linear the yval values at the end:
yval = 10**yval
The full working code is here:
%matplotlib inline
from PIL import Image
from scipy import *
from pylab import *
im = array(Image.open('fig1.jpg'))
hh = im.shape[0]
ww = im.shape[1]
imshow(im)
print(im[100,0,:])
Col = array([255,0,0])
bnd = 30
ymax_lin = log10(0.5)
ymin_lin = log10(2e-4)
yax = linspace(ymax_lin,ymin_lin,hh)
xax = linspace(1,14,ww)
for i in range(hh):
for j in range(ww):
im[i,j,:] = 255*(any(im[i,j,:]>Col+bnd) or any(im[i,j,:]<Col-bnd))
mapim = abs(im[:,:,0]/255-1).astype(bool)
yval = array([average(yax[mapim[:,t]]) for t in range(ww)])
yval = 10**yval
rlt = interp(range(100),xax,yval)
When running the following code segment, the last two lines of code plt.imshow(X[0,:,:]) plt.show() keep generating the error message of Illegal instruction (core dumped) The X shape is (1, 572, 572). May I know what can be the reason of this?
import os
import numpy as np
import matplotlib.pyplot as plt
import pylab
from scipy.ndimage.filters import gaussian_filter
from scipy import ndimage
np.random.seed(1234)
pylab.rcParams['figure.figsize'] = (10.0, 8.0)
nx = 572
ny = 572
sigma = 10
plateau_min = -2
plateau_max = 2
r_min = 1
r_max = 200
def create_image_and_label(nx,ny):
x = np.int(np.random.rand(1)[0]*nx)
y = np.int(np.random.rand(1)[0]*ny)
image = np.ones((nx,ny))
label = np.ones((nx,ny))
image[x,y] = 0
image_distance = ndimage.morphology.distance_transform_edt(image)
r = np.random.rand(1)[0]*(r_max-r_min)+r_min
plateau = np.random.rand(1)[0]*(plateau_max-plateau_min)+plateau_min
label[image_distance <= r] = 0
label[image_distance > r] = 1
label = (1 - label)
image_distance[image_distance <= r] = 0
image_distance[image_distance > r] = 1
image_distance = (1 - image_distance)*plateau
image = image_distance + np.random.randn(nx,ny)/sigma
return image, label[92:nx-92,92:nx-92]
def create_batch(nx,ny,n_image):
X = np.zeros((n_image,nx,ny))
Y = np.zeros((n_image,nx-184,ny-184,2))
for i in range(n_image):
X[i,:,:],Y[i,:,:,1] = create_image_and_label(nx,ny)
Y[i,:,:,0] = 1-Y[i,:,:,1]
return X,Y
X,Y = create_batch(nx,ny,1)
print(X.shape)
plt.imshow(X[0,:,:])
plt.show()
Works fine for me. Try upgrading and/or reinstalling your libraries and/or Python.
If it still fails, consider using gdb to get a stack trace (hint: gdb /path/to/your/python). Then submit a bug report to matplotlib, as suggested by #nneonneo.
I need to plot the mathieu characteristic parameters for various q. The plot should show 'flute' shapes going from wide on the left, to very narrow on the right. The code below does this, but it also introduces a handful of inter-band jumps (obvious from the plotted figure). How can I fix this?
Thank you!
AM
import numpy as np
import scipy as sp
import scipy.special as spfun
from matplotlib import pyplot as plt
uplim =120#E_rec
Npts =1000
Nstates =8
q = np.linspace(0, uplim/4.0, Npts)
EA = np.zeros([Npts,Nstates])
EB = np.zeros([Npts,Nstates])
U = 4*q
print np.shape(EA) #plt.fill_between(U, EA[:,i], EB[:,i]) #plt.plot(U,Ea,U,Eb)
for i in range(Nstates):
a = spfun.mathieu_a(i,q)
b = spfun.mathieu_b(i+1,q)
EA[:,i] = a + 2*q
EB[:,i] = b + 2*q
plt.fill_between(U, EA[:,i], EB[:,i]) #plt.plot(U,Ea,U,Eb)
print np.shape(EA) #plt.fill_between(U, EA[:,i], EB[:,i]) #plt.plot(U,Ea,U,Eb)
plt.show()
EDIT As DSM and pv have pointed out, this is a scipy bug. The glitches get worse as you go out further. What I ended up doing was exporting tables of values that I wanted from Mathematica, and importing them into python and interpolating. Not great, but works.
I tried computing this with the latest release of the NAG Library for Python which included a new Mathieu function routine.
I pushed a little harder -- more states and a higher value of uplim.
%matplotlib inline
import numpy as np
import scipy as sp
import scipy.special as spfun
from naginterfaces.library import specfun
from matplotlib import pyplot as plt
uplim =150#E_rec
Npts = 4000
Nstates = 10
q = np.linspace(0, uplim/4.0, Npts)
EA = np.zeros([Npts,Nstates])
EB = np.zeros([Npts,Nstates])
U = 4*q
plt.figure(figsize=(15,8))
plt.subplot(1,2,1)
plt.title('Using SciPy')
for i in range(Nstates):
a = spfun.mathieu_a(i,q)
b = spfun.mathieu_b(i+1,q)
EA[:,i] = a + 2*q
EB[:,i] = b + 2*q
plt.fill_between(U, EA[:,i], EB[:,i]) #plt.plot(U,Ea,U,Eb)
plt.subplot(1,2,2)
plt.title('Using NAG')
for i in range(Nstates):
a = [specfun.mathieu_ang_periodic_real(ordval=i, q=qi, parity=0, mode=3)[2] for qi in q]
b = [specfun.mathieu_ang_periodic_real(ordval=i+1, q=qi, parity=1, mode=3)[2] for qi in q]
EA[:,i] = a + 2*q
EB[:,i] = b + 2*q
plt.fill_between(U, EA[:,i], EB[:,i])
plt.show()
This uses Mark 27 of the NAG Library and version 1.2.1 of ScipPy