Related
I have a fits datacube in Python where I need to fit the spectra of each pixel in the cube. My code for fitting just one spectrum works great, but for some reason I can't figure out how to translate that into fitting each pixel (100 pixels total for a 10by10).
ngc2617 = fits.open('NGC2617.fits')[1]
cube2617 = SpectralCube.read(ngc2617)
data2617 = ngc2617.data
nz,ny,nx = np.shape(data2617)
obs_2617 = cube2617.spectral_axis
z_2617 = 0.014326 #simbad
rest_2617 = np.asarray(obs_2617 / (1+z_2617))
flux_2617 = data2617[:,172,142]
flux_2617[np.isnan(flux_2617)]=0
halpha_chans = np.asarray(np.where((rest_2617 > 6365) & (rest_2617 < 6715)))
halphawaves = np.asarray(rest_2617[halpha_chans]).T
halphaflux = np.asarray(flux_2617[halpha_chans]).T
cont_chans = np.asarray(np.where((rest_2617 > 5500) & (rest_2617 < 5510)))
cont_2617 = np.asarray(flux_2617[cont_chans]).T
x_halpha = halphawaves.flatten()
y_halpha = halphaflux.flatten()
c = 2.998 * 10**5 #km/s
plt.figure(figsize=[10,8])
plt.subplot(2,1,1)
plt.plot(x_halpha,y_halpha, '--', label = 'data')
def Gauss(x, A, x0, fwhm):
sigma = (fwhm * x0) / (2.355 * c)
return A * np.exp(-(x - x0) ** 2 / (2 * sigma ** 2))
def func(x, A0, A1, x0, fwhm, fwhm1, cont):
param1 = cont
param2 = Gauss(x, A0, x0 - 14.75, fwhm) + Gauss(x, A1, x0, fwhm) + Gauss(x, A0*3, x0 + 20.66, fwhm) + Gauss(x, A1, x0, fwhm1)
return param1 + param2
cont_init = np.average(cont_2617)
A0_init = np.max(y_halpha[0:150])-cont_init
A1_init = np.max(y_halpha)-cont_init
x0_init = x_halpha[np.where(y_halpha==np.max(y_halpha))][0]
fwhm_init = (x_halpha[np.where(y_halpha==np.max(y_halpha))][0] - x_halpha[np.where((np.min(abs(np.max(y_halpha)/2 - y_halpha))))][0])*2
fwhm1_init = (x_halpha[np.where(y_halpha==np.max(y_halpha))][0] - x_halpha[np.where((np.min(abs(np.max(y_halpha)/2 - y_halpha[0:150]))))][0])*2
parameters, covariance = curve_fit(func, x_halpha, y_halpha, p0=[A0_init, A1_init, x0_init, fwhm_init, fwhm1_init, cont_init])
fit_y = func(x_halpha, *parameters)
fit1_NII = Gauss(x_halpha, A0_init, parameters[2]-14.75, parameters[3]) + parameters[5]
fit2_NII = Gauss(x_halpha, A0_init, parameters[2]+20.66, parameters[3]) + parameters[5]
fit_Halph = Gauss(x_halpha, A1_init, parameters[2], parameters[3]) + parameters[5]
plt.plot(x_halpha, fit_y, '-', label='full fit')
plt.plot(x_halpha, fit1_NII, '-', label='NII 6549.86 fit')
plt.plot(x_halpha, fit2_NII, '-', label='NII 6585.27 fit')
plt.plot(x_halpha, fit_Halph, '-', label='H\u03B1 fit')
plt.title('NGC2617 H\u03B1 & NII Spectra of Central Point with Gaussian Fit', fontsize = 15)
plt.xlabel('wavelength [$\AA$]', fontsize = 12)
plt.ylabel(r'flux [10$^{-20}$ $erg * s^{-1}$ * $cm^{-2}$ * $\AA^{-1}$]', fontsize = 12)
plt.grid(True)
plt.legend()
plt.subplot(2,1,2)
plt.plot(np.linspace(0,0,6800), color = 'r', label = '0 point')
plt.scatter(x_halpha, y_halpha-fit_y, marker = 'o', label='residuals')
plt.xlim(halphawaves[0],halphawaves[-1])
plt.xlabel('wavelength [$\AA$]', fontsize = 12)
plt.ylabel('residuals', fontsize = 12)
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
this is my code for the single spectrum...can anyone help me create a loop that will do this but for a full cube? Thanks!
I'm doing a free fall caluculations (really simple) and would like to plot each instance of height of the objects - that is the height of the object to be displayed as it 'falls' down. I tried running it throught a for loop, but i just get the end result plotted. What would i need to do to dislplay the object as it falls, for each individual - not just the end result.
Here is my code:
#Input parameters
y1 = 490 #starting position
y2 = 0 #ground
g = -9.81 #gravity
VY = 0 #starting speed
import math
import numpy as np
import matplotlib.pyplot as plt
sqrt_part = math.sqrt(VY**2-2*g*(y1-y2))
t1 = - VY - sqrt_part/g
t2 = - VY + sqrt_part/g
if t1 > 0:
t = t1
else:
t = t2
print('t = ' + str(t) + ' ' + 's')
t_space = np.linspace(0,t,50)
y_t = y1 + VY * t_space + 0.5 * g * t_space**2
v_t = abs(y_t[1:] - y_t[0:-1])/abs(t_space[0:-1] - t_space[1:])
plt.plot(t_space, y_t, 'go')
plt.plot(t_space[1:], v_t, 'r--')
for i in range(np.size(t_space)):
plt.plot(t_space[i], y_t[i], 'go')
The for loop displays the same as the plot above it, but i would like it to update and show the 'ro' as it moves thorught time. How would i do that?
On the left is what i get, on the right is what i want
enter image description here
Please, take a look at matplotlib animation api.
#Input parameters
y1 = 490 #starting position
y2 = 0 #ground
g = -9.81 #gravity
VY = 0 #starting speed
import math
import numpy as np
import matplotlib.pyplot as plt
sqrt_part = math.sqrt(VY**2-2*g*(y1-y2))
t1 = - VY - sqrt_part/g
t2 = - VY + sqrt_part/g
if t1 > 0:
t = t1
else:
t = t2
print('t = ' + str(t) + ' ' + 's')
t_space = np.linspace(0,t,50)
y_t = y1 + VY * t_space + 0.5 * g * t_space**2
v_t = np.abs((np.roll(y_t, -1) - y_t) / (np.roll(t_space, -1) - t_space))
v_t = np.roll(v_t, 1)
v_t[0] = 0
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
# create two empty lines
ln_y, = plt.plot([], [], 'go', label="y")
ln_v, = plt.plot([], [], 'r--', label="v")
def init():
ax.set_xlim(0, max(t_space))
ax.set_ylim(0, max(y_t))
ax.set_xlabel("t")
ax.legend()
return ln_y, ln_v
def update(i):
# i represents the index of the slice to use at the current frame
ln_y.set_data(t_space[:i], y_t[:i])
ln_v.set_data(t_space[:i], v_t[:i])
return ln_y, ln_v,
ani = FuncAnimation(fig, update, frames=range(len(v_t)),
init_func=init, blit=False, repeat=False)
plt.show()
I am currently working on a Yee Solver script for uni, but when I try to animate my 3D graph, the graph is not what is expected. It works for a 2D plot, but I can't seem to translate that into 3D. From my understanding, set_data and set_3d_properties need a 1D array to work, which I am inputting.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
from matplotlib.widgets import Slider
# Program Variables
wv_lgth_num = 10
graph_type = '3d'
t = 0
# Physical Constants
c = 3e8
mu_r = 1
eps_r = 1
# Source Constants
f = 2e9
omega = 2*f*(np.pi)
amp = 1.0
wv_lgth = c/f
period = 1/f
# Step size
dz = wv_lgth/20
dt = ((c/f)/20)/c
#dt = ((1/f)/20)/1
# Axis Grids
z_grid = np.arange(0,wv_lgth_num*wv_lgth,dz)
t_grid = np.arange(0,10*period,dt)
# Number of steps
num_z = z_grid.size
num_t = t_grid.size
# Coefficients
coe_E = c*dt/(eps_r*dz)
coe_H = c*dt/(mu_r*dz)
# E and H Matricies
E_mat = np.zeros((num_z,num_t))
H_mat = np.zeros((num_z,num_t))
# Generating Values for E and H
for time in range(0,num_t-1):
for pos in range(0,num_z-1):
# Source Wave
if pos == 0:
H_mat[0,time] = amp*np.sin(omega*t_grid[time])
# All cases of Yee Solver
if pos == 1:
if time == 0:
H_mat[1,0] = 0
E_mat[0,0] = 0
else:
H_mat[1,time] = H_mat[1,time-1] + coe_H*(E_mat[1,time-1] - E_mat[0,time-1])
E_mat[0,time] = E_mat[0,time-1] + coe_E*(H_mat[1,time] - H_mat[0,time])
if pos > 1 and pos != num_z-1:
if time == 0:
H_mat[pos,0] = 0
E_mat[pos-1,0] = 0
if time > 0:
H_mat[pos,time] = H_mat[pos,time-1] + coe_H*(E_mat[pos,time-1] - E_mat[pos-1,time-1])
E_mat[pos-1,time] = E_mat[pos-1,time-1] + coe_E*(H_mat[pos,time] - H_mat[pos-1,time])
if pos == num_z-1:
if time == 0:
H_mat[num_z-1,0] = 0
E_mat[num_z-2,0] = 0
E_mat[num_z-1,0] = 0
if time > 0:
H_mat[num_z-1,time] = H_mat[num_z-1,time-1] + coe_H*(E_mat[num_z-1,time-1] - E_mat[num_z-2,time-1])
E_mat[num_z-2,time] = E_mat[num_z-2,time-1] + coe_E*(H_mat[num_z-1,time] - H_mat[num_z-2,time])
E_mat[num_z-1,time] = E_mat[num_z-2,time]
def update(val):
t = slider_time.val
if graph_type == '2d':
a.set_ydata(E_mat[:,t])
b.set_ydata(H_mat[:,t])
if graph_type == '3d':
a.set_3d_properties(E_mat[:,t])
a.set_data(z_grid,np.zeros((num_z,num_t))[:,t])
b.set_3d_properties(np.zeros((num_z,num_t))[:,t])
b.set_data(z_grid,H_mat[:t])
fig.canvas.draw_idle()
print(H_mat)
print(H_mat[:,t].size)
print(z_grid)
print(np.zeros((num_z,num_t))[:,t].size)
# Creating plot
if graph_type == '3d':
fig, ax = plt.subplots()
ax = plt.axes(projection='3d')
b, = ax.plot3D(z_grid,H_mat[:,t],np.zeros((num_z,num_t))[:,t], label='H')
a, = ax.plot3D(z_grid,np.zeros((num_z,num_t))[:,t],E_mat[:,t], label='E')
plt.title('Light Wave')
ax.set_xlabel('z')
ax.set_ylabel('x')
ax.set_zlabel('y')
plt.legend()
ax_time = plt.axes([0.25,0.1,0.65,0.03])
slider_time = Slider(ax_time,'Time',0,num_t-2,valinit=0,valstep=1)
slider_time.on_changed(update)
plt.show()
if graph_type == '2d':
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
a, = plt.plot(z_grid,E_mat[:,t], label='E (yz plane)')
b, = plt.plot(z_grid,H_mat[:,t], label='H (xz plane)')
plt.title('Light Wave')
plt.xlabel('z')
plt.ylabel('x')
plt.legend()
ax_time = plt.axes([0.25,0.1,0.65,0.03])
slider_time = Slider(ax_time,'Time',0,num_t-2,valinit=0,valstep=1)
slider_time.on_changed(update)
plt.show()
Any help would be appreciated. The middle for loop is just generating my functions, using the Yee Method.
Here is my issue: I have an embedded matplotlib figure in a Qt5 application. When I press the button "edit axis, curve and image parameter", I select my concerned subplot, but only the tab "axis" options appears. it is missing tabs for "curve" and "image".
actual picture
whereas I should have had something like this:
targeted picture
If anyone knows why...
Probably the answer is easy:
If there is no curve (line) in the plot, there will be no "Curves" tab.
If there is no image in the plot, there will be no "Images" tab.
class View2D(MapView):
def show(self, som, what='codebook', which_dim='all', cmap=None,
col_sz=None, desnormalize=False):
(self.width, self.height, indtoshow, no_row_in_plot, no_col_in_plot,
axis_num) = self._calculate_figure_params(som, which_dim, col_sz)
self.prepare()
if not desnormalize:
codebook = som.codebook.matrix
else:
codebook = som._normalizer.denormalize_by(som.data_raw, som.codebook.matrix)
if which_dim == 'all':
names = som._component_names[0]
elif type(which_dim) == int:
names = [som._component_names[0][which_dim]]
elif type(which_dim) == list:
names = som._component_names[0][which_dim]
while axis_num < len(indtoshow):
axis_num += 1
ax = plt.subplot(no_row_in_plot, no_col_in_plot, axis_num)
ind = int(indtoshow[axis_num-1])
min_color_scale = np.mean(codebook[:, ind].flatten()) - 1 * np.std(codebook[:, ind].flatten())
max_color_scale = np.mean(codebook[:, ind].flatten()) + 1 * np.std(codebook[:, ind].flatten())
min_color_scale = min_color_scale if min_color_scale >= min(codebook[:, ind].flatten()) else \
min(codebook[:, ind].flatten())
max_color_scale = max_color_scale if max_color_scale <= max(codebook[:, ind].flatten()) else \
max(codebook[:, ind].flatten())
norm = matplotlib.colors.Normalize(vmin=min_color_scale, vmax=max_color_scale, clip=True)
mp = codebook[:, ind].reshape(som.codebook.mapsize[0],
som.codebook.mapsize[1])
# pl = plt.pcolor(mp[::-1], norm=norm, cmap='jet')
pl = plt.imshow(mp[::-1], interpolation='nearest', origin='lower',cmap='jet')
plt.axis([0, som.codebook.mapsize[1], 0, som.codebook.mapsize[0]])
plt.title(names[axis_num - 1])
ax.set_yticklabels([])
ax.set_xticklabels([])
plt.colorbar(pl)
plt.show()
Hi I'm having trouble in getting matplotlib animation to work
The idea is to animate throughout a few lists and images.
a[0] is basically time points/images to plot/imshow
"timepoints[a[0].astype(np.int)][:i]/60" is simply the indexed "real time" to be in the x axis
May anyone give me some hints?
Appreciated
def draw_plot(resolution,timepoints,a,ts_g,ts_r,contrast):
def animate(i):
#~ ax.cla()
#~ ax2.cla()
#~ ax3.cla()
#~ ax4.cla()
print "ax"
ax.errorbar(timepoints[a[0].astype(np.int)][:i]/60,list(a[1][0])[:i], yerr=list(a[4][0])[:i], fmt='-o',color='green')
ax.errorbar(timepoints[a[0].astype(np.int)][:i]/60,list(a[1][1])[:i], yerr=list(a[4][1])[:i], fmt='-o',color='red')
ax.axis([0,timepoints[a[0].astype(np.int)][-1]/60,np.min(np.concatenate((a[1][0],a[1][1])))*0.75,np.max(np.concatenate((a[1][0],a[1][1])))*1.3])
ax.set_autoscale_on(False)
print "ax2"
ax2.plot(timepoints[a[0].astype(np.int)][:i]/60,list(a[2][0])[:i],color='green')
ax2.plot(timepoints[a[0].astype(np.int)][:i]/60,list(a[2][1])[:i],color='red')
ax2.axis([0,timepoints[a[0].astype(np.int)][-1]/60,np.min(np.concatenate((a[2][0],a[2][1])))*0.75,np.max(np.concatenate((a[2][0],a[2][1])))*1.3])
ax2.set_autoscale_on(False)
j = int(a[0][i]-1)
r = ts_r[j]#.T
g = ts_g[j]#.T
max_ = contrast[3]
min_ = contrast[2] #~
r[r>max_]=max_
r[r<min_]=min_
r -= min_
r *= _16bit/(max_-min_)#r.max()
max_ = contrast[1]
min_ = contrast[0]
g[g>max_]=max_
g[g<min_]=min_
g -= min_
g *= _16bit/(max_-min_)#r.max()
#~
g_16 = g
r = (r*ratio).astype(np.uint8)
g = (g*ratio).astype(np.uint8)
b = np.zeros(r.shape).astype(np.uint8)
centered = np.dstack((r,g,b)).astype(np.uint8)
#~ aa = np.dstack((np.zeros(ts[0].shape).T,ts[j].T,np.zeros(ts[0].shape)))
print "ax3"
ax3.imshow(centered)
ax3.plot(list(a[5][0]/resolution)[:i],list(512-a[5][1]/resolution)[:i],color='blue')
ax3.axis([0,512,512,0])
print "ax4"
ax4.imshow(centered)
x = int (list(a[5][0]/resolution)[i])
y = int (list(512-a[5][1]/resolution)[i])
#~ ax4.axis([512,0,512,0])
ax4.axis([x-10,x+10,y-10,y+10])
ax4.get_xaxis().set_visible(False)
ax4.get_yaxis().set_visible(False)
print "ax5"
ax5.imshow(g_16,cmap='gray')
#~ x = int (list(a[5][0]/resolution)[i])
#~ y = int (list(512-a[5][1]/resolution)[i])
#~ ax4.axis([512,0,512,0])
ax5.axis([x-10,x+10,y-10,y+10])
ax5.get_xaxis().set_visible(False)
ax5.get_yaxis().set_visible(False)
plt.draw()
fig = plt.figure()
ax = plt.subplot2grid((2,5), (0,0),colspan=2)
ax2 = plt.subplot2grid((2,5), (1,0),colspan=2)
ax3 = plt.subplot2grid((2,5), (0, 2), colspan=2,rowspan=2)
ax4 = plt.subplot2grid((2,5), (0,4))
ax5 = plt.subplot2grid((2,5), (1, 4))
line, = ax.plot([], [], lw=2)
line2, = ax2.plot([], [], lw=2)
ani = animation.FuncAnimation(fig, animate, frames= len(a[0]), interval=20000,repeat=False,blit=True)
plt.show()
Alright, like this it works.
However:
1- I can't return the list with several axes/lines (lines = [] ) I have to return each one individually (errorline_g, etc, etc).It works with normal ax.plots, so I don't know why errorbars can't do the same.
same with Vertical bars. I had to use errorline_g, ( bottomsg,topsg), (vertsg, )= ax.errorbar([],[],yerr=1,fmt='-o',color='green')
If I don't unpack the tuple at declaration if I would try to return vertsg or vertsg[0] it doesn't work.
def draw_plot(resolution,timepoints,a,ts_g,ts_r,contrast,csvfile):
fig = plt.figure()
ax = plt.subplot2grid((2,5), (0,0),colspan=2)
ax2 = plt.subplot2grid((2,5), (1,0),colspan=2)
ax3 = plt.subplot2grid((2,5), (0, 2), colspan=2,rowspan=2)
ax4 = plt.subplot2grid((2,5), (0,4))
ax5 = plt.subplot2grid((2,5), (1, 4))
ax.axis([0,(timepoints[a[0].astype(np.int)-1][-1]/60)+5,np.min(np.concatenate((a[1][0],a[1][1])))*0.75,np.max(np.concatenate((a[1][0],a[1][1])))*1.3])
ax.set_autoscale_on(False)
ax2.axis([0,(timepoints[a[0].astype(np.int)-1][-1]/60)+5,np.min(np.concatenate((a[2][0],a[2][1])))*0.75,np.max(np.concatenate((a[2][0],a[2][1])))*1.3])
ax2.set_autoscale_on(False)
#~ ax3.axis([0,512,512,0])
ax3.get_yaxis().set_visible(False)
ax4.get_xaxis().set_visible(False)
ax4.get_yaxis().set_visible(False)
ax5.get_xaxis().set_visible(False)
ax5.get_yaxis().set_visible(False)
errorline_g, ( bottomsg,topsg), (vertsg, )= ax.errorbar([],[],yerr=1,fmt='-o',color='green')
errorline_r, ( bottomsr,topsr), (vertsr, ) = ax.errorbar([],[],yerr=1,fmt='-o',color='red')
lines = []
lines += ax2.plot([],[], color='green', lw=2)
lines += ax2.plot([],[], color='red', lw=2)
lines += ax3.plot([],[],color='blue')
def animate(i=0):
#~ ax.cla()
#~ ax2.cla()
#~ ax3.cla()
#~ ax4.cla()
x = timepoints[a[0].astype(np.int)][:i+1]/60
y = list(a[1][0])[:i+1]
g_berr = np.array(a[1][0])[:i+1]+np.array(a[4][0])[:i+1]
g_terr = np.array(a[1][0])[:i+1]-np.array(a[4][0])[:i+1]
r_berr =np.array(a[1][1])[:i+1]+np.array(a[4][1])[:i+1]
r_terr =np.array(a[1][1])[:i+1]-np.array(a[4][1])[:i+1]
errorline_g.set_data(x,y)
bottomsg.set_data(x,g_berr)
topsg.set_data(x,g_terr)
vertsg.set_segments(zip(zip(x,g_terr),zip(x,g_berr)))
#~ ax.errorbar(timepoints[a[0].astype(np.int)][:i]/60,list(a[1][1])[:i], yerr=list(a[4][1])[:i], fmt='-o',color='red')
ax.fill_between(x, g_berr, g_terr,
alpha=0.05, edgecolor='green', facecolor='green')
#~ print errorline_g
y = list(a[1][1])[:i+1]
errorline_r.set_data(x,y)
bottomsr.set_data(x,r_berr)
topsr.set_data(x,r_terr)
ax.fill_between(x, r_berr, r_terr,
alpha=0.08, edgecolor='red', facecolor='red')
vertsr.set_segments(zip(zip(x,r_terr),zip(x,r_berr)))
lines[0].set_data(timepoints[a[0].astype(np.int)][:i+1]/60,list(a[2][0])[:i+1])
lines[1].set_data(timepoints[a[0].astype(np.int)][:i+1]/60,list(a[2][1])[:i+1])
j = int(a[0][i]-1)
r = ts_r[j]#.T
g = ts_g[j]#.T
max_ = contrast[3]
min_ = contrast[2] #~
r[r>max_]=max_
r[r<min_]=min_
r -= min_
r *= _16bit/(max_-min_)#r.max()
max_ = contrast[1]
min_ = contrast[0]
g[g>max_]=max_
g[g<min_]=min_
g -= min_
g *= _16bit/(max_-min_)#r.max()
g_16 = g
r = (r*ratio).astype(np.uint8)
g = (g*ratio).astype(np.uint8)
b = np.zeros(r.shape).astype(np.uint8)
centered = np.dstack((r,g,b)).astype(np.uint8)
ax3.imshow(centered)
lines[2].set_data(list(a[5][0]/resolution)[:i],list(512-a[5][1]/resolution)[:i])
#~ ax3.axis([0,512,512,0])
ax4.imshow(centered)
x = int (list(a[5][0]/resolution)[i])
y = int (list(512-a[5][1]/resolution)[i])
#~#
ax4.axis([x-10,x+10,y-10,y+10])
ax5.imshow(g_16,cmap='gray')
ax5.axis([x-10,x+10,y-10,y+10])
#~ plt.draw()
return errorline_g, errorline_r, lines[0], lines[1],lines[2],bottomsg,topsg,bottomsr,topsr,ax,ax2,ax3,ax4,ax5,vertsg
def init():
errorline_g.set_data([],[])
errorline_r.set_data([],[])
for line in lines:
line.set_data([],[])
#~ lines[0].set_data([],[])
#~ lines[1].set_data([],[])
ax3.imshow(np.zeros(ts_r[0].shape))
ax4.imshow(np.zeros(ts_r[0].shape))
ax5.imshow(np.zeros(ts_r[0].shape))
return errorline_g, errorline_r, lines[0], lines[1], lines[2],ax,ax2,ax3,ax4,ax5
ani = animation.FuncAnimation(fig, animate, init_func=init, frames= len(a[0]), interval=500,repeat=False,blit=True)
plt.show()
#~ ani.save('./mp4/'+csvfile.strip('.csv').strip('./')+".mp4")
plt.close()