Interpolation result in python is rotated 90 degrees to the right - python

I have constructed an interpolation code using rbf in python and following this tutorial. More precisely, the code displayed at 04:57.
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
import pylab as py
import scipy
token = open('Ydata_48_of_50.txt','r')
linestoken=token.readlines()
tokens_column_numberX = 0
tokens_column_numberY = 1
tokens_column_numberF = 2
resulttokenX=[]
resulttokenY=[]
resulttokenF=[]
for x in linestoken:
resulttokenX.append(x.split()[tokens_column_numberX])
resulttokenY.append(x.split()[tokens_column_numberY])
resulttokenF.append(x.split()[tokens_column_numberF])
token.close()
resulttokenX2 = np.array(resulttokenX)
resulttokenY2 = np.array(resulttokenY)
resulttokenF2 = np.array(resulttokenF)
newfunc=interpolate.Rbf(resulttokenX2.astype('float'), resulttokenY2.astype('float'), resulttokenF2.astype('float'), function='multiquadric')
xnew, ynew=np.mgrid[340:350:100j, 23:32:100j]
fnew=newfunc(xnew, ynew)
#create image plot
py.figure(1)
py.clf()
py.imshow(fnew, extent=[340, 350, 23, 32], cmap=py.cm.jet)
The code aboce is a sample of my program. And the result can be seen in this image
Unfortunately, I am doing something wrong. The resulting interpolation should look like a 90 degree turn of the previous image.
I have tried to alter the values of np.np.mgrid but I haven't found any combination which returns what I want. Note that I am working with latitudes and longitudes. I have 19 values of latitude and 21 of longitude in my original data.
Any idea on what might be going on?

In the end, I have managed to "fix" this by using a combination of flipped lists and changing the axis. This is the code:
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
import pylab as py
import scipy
token = open('Ydata_48_of_50.txt','r')
linestoken=token.readlines()
tokens_column_numberX = 0
tokens_column_numberY = 1
tokens_column_numberF = 2
resulttokenX=[]
resulttokenY=[]
resulttokenF=[]
for x in linestoken:
resulttokenX.append(x.split()[tokens_column_numberX])
resulttokenY.append(x.split()[tokens_column_numberY])
resulttokenF.append(x.split()[tokens_column_numberF])
token.close()
resulttokenXflip=resulttokenX[::-1]
resulttokenYflip=resulttokenY[::-1]
resulttokenFflip=resulttokenF[::-1]
resulttokenX2 = np.array(resulttokenX)
resulttokenX2flip = np.array(resulttokenXflip)
resulttokenY2 = np.array(resulttokenY)
resulttokenY2flip = np.array(resulttokenYflip)
resulttokenF2 = np.array(resulttokenF)
resulttokenF2flip = np.array(resulttokenFflip)
#El error tiene que venir del hecho de que Y2 está definida de menor a mayor
len(resulttokenX2)
newfunc=scipy.interpolate.Rbf(resulttokenY2flip.astype('float'), resulttokenX2.astype('float'), resulttokenF2.astype('float'), function='linear')
xnew, ynew=np.mgrid[ 23:32:90j, 340:350:100j]
fnew=newfunc(xnew, ynew)
#create image plot
py.figure(1)
py.clf()
py.imshow(fnew, extent=[ 340, 350, 23,32], cmap=py.cm.jet)

Related

Not able to get any graphs as output

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')

Obtaining an isosurface from 3D data and the corresponding indices

I have a 3D numpy array of temperature values on a grid. From this I can compute the gradients using dTdx, dTdy, dYdz = np.gradient(T). Now I'm only interested in the values of the gradients on the isosurface where the temperature is 900. What I want to do is something like (pseudo-codish):
import nympy as np
def regular(x,y,z,q=100,k=175,a=7.1e-5):
R = np.sqrt(x**2+y**2+z**2)
return 100 / (2*np.pi*k) * (1/R) * np.exp(-0.5/a*(R+x))
x = np.arange(-1.5,0.5+res/2,res)*1e-3
y = np.arange(-1.0,1.0+res/2,res)*1e-3
z = np.arange(0.0,0.5+res/2,res)*1e-3
Y,X,Z = np.meshgrid(y,x,z)
T = regular(X,Y,Z)
dTdx, dTdy, dYdz = np.gradient(T)
(xind,yind,zind) = <package>.get_contour_indices(X,Y,Z,T,value=900)
x_gradients_at_isosurface = dTdx[xind,yind,zind]
...
I've tried:
import numpy as np
from skimage import measure
contour_data = measure.find_contours(T[:,:,0],900)
contour_data = np.int_(np.round(contour_data[0]))
xs,ys = contour_data[:,0],contour_data[:,1]
gradients_of_interest = np.array([G[x,y,0] for x,y in zip( xs,ys )])
which works fine, but only works for 2D data. I'm looking for the 3D equivalent. I've found the following:
import plotly.graph_objects as go
surf = go.Isosurface(x=X.flatten(),y=Y.flatten(),z=Z.flatten(),value=T.flatten(),isomin=900,isomax=900)
fig = go.Figure(data=surf)
plt.show()
But I'm not interested in plotting it. I want to know the indices where the temperature is T=900 so I can use it on the gradients. Any ideas?
You need skimage.measure.marching_cubes.

spyder plotting with dots for a pdf

I am trying to plot with dots hoping in the end i can get a probability density function simulation. My code is:
import random
import math
from numpy import *
from matplotlib.pyplot import *
import matplotlib.pyplot as pl
clock_offset=3000
y=0
p=0.50
for i in range (40):
x = random.random()
if x < p:
clock_offset+=1
for 'bo' in (clock_offset,y):
y+=1
pl.plot(clock_offset,y,'bo')
pl.axis([2980, 3040, 0, 40])
y=0
else:
clock_offset-=1
for 'bo' in (clock_offset,y):
y+=1
pl.plot(clock_offset,y,'bo')
pl.axis([2980, 3040, 0, 40])
y=0
The problem is i can't write a for loop that makes y+=1, when that place (clock_offset,y) has already been occupied with a dot. Any solutions?
I'm not sure what this code of yours is supposed to do. But take a look at this answer of mine that explains how to get a random number on a distribution. Bellow I gave you a rewrite of that C++ code into python.
import random
import math
import numpy as np
import matplotlib.pyplot as plt
def GausPDF(x, a=1., b=2., c=3.):
return a*math.exp( -((x-b)*(x-b)/(2*c*c) ))
def random_on_PDF(PDF, top, bottom, maxPDF):
x = (top-bottom)*np.random.random()+bottom
y = maxPDF*random.random()
while(y>PDF(x)):
x = (top-bottom)*np.random.random()+bottom
y = maxPDF*random.random()
return x,y
x, y, = list(), list()
for i in range(0, 1000):
a,b = random_on_PDF(GausPDF, 10., -5., 1.)
x.append(a)
y.append(b)
plt.scatter(x,y)
plt.show()
Using this code and THIS matplotlib example directly, you can simulate how random voting affects/builds a PDF.
Is that what you're after?

How to index List/ numpy array in order to plot the data with matplotlib

I have a function f(x,t) = cos(t)*t + x and i want to display the change of the result over the width x and time t at discretised time steps t_i and discretised width steps x_j.
Now I am a while here on SX and feel really embarrassed to only can post such little code or in other words nothing (since nothing worked I have done...):
Nevertheless if someone has the time to help, I`d appreciate it.
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as pyplot
from astropy.io.ascii.latex import AASTex
def func(xi, ti):
res = np.cos(ti)*ti + xi
return res
timeSpacing = 100
timeStart = 0
timeEnd = 1
time = np.linspace(timeStart, timeEnd, timeSpacing)
widthSpacing = 300
widthStart = 0
widthEnd = 3
width = np.linspace(widthStart, widthEnd, widthSpacing)
resultList = [None]*timeSpacing
resultListInner = [None]*widthSpacing
for i, ithTime in enumerate(time):
for j, jthWidth in enumerate(width):
aas = np.zeros_like(width)
aas.fill(ithTime)
resultListInner[j] = ithTime, jthWidth, func(jthWidth, aas)
resultList[i] = resultListInner
So how do I correctly index the list and array and plot my data using matplotlib?
My plot should look like this:
where in my case the aperature should be the width x, the sky annulus is my time t and the RMS is my func(x,t).
A couple of points:
Numpy provides a very nice function for doing differences of array elements: diff
Matplotlib uses plot_wireframe for creating a plot that you would want (also using Numpy's meshgrid)
Now, combining these into what you may want would look something like this.
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
def func(xi, ti):
res = np.cos(ti)*np.sin(xi)
return res
timeSpacing = 20
timeStart = 0
timeEnd = 1
time = np.linspace(timeStart, timeEnd, timeSpacing)
widthSpacing = 50
widthStart = 0
widthEnd = 3
width = np.linspace(widthStart, widthEnd, widthSpacing)
X,T = np.meshgrid(width,time)
F = func(X,T)
DF = np.diff(np.diff(F,axis=0),axis=1)
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.plot_wireframe(X[:-1,:-1],T[:-1,:-1],DF)
plt.show()
Note that diff is applied twice: once in each dimension axis= . I have also changed the toy function you provided to something that actually looks decent in this case.
For your more general use, it seems that you would want to just collect all of your F data into a 2D array, then proceed from the DF = line.

Mathieu Characteristics Cross When Plotted

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

Categories

Resources