Build a 3D array for 754 spectra - python

My problem is I have two arrays, one with my data (spectra), one is just filled up from 1 to 128 (1D arrays). I wonder how I can do to build a 3D array from these. I tried to use numpy.vstack but is seems that I have to precise in parameters the different arrays. I'm sure it's nothing complicated but I am a bit stuck right now. The idea is to build an array like this (and then to print the 3D curve) :
The goal is to have the right spectra when I move down the wavenumber. In 2D I have for instance :
With the following code :
import numpy as np
import array
import matplotlib.pyplot as plt
num_lon = 128
num_lat = 128
tmpfile = "180523_WT_striatum_#1.dat"
fileobj = open(tmpfile, mode='rb')
fileobj.seek(1020)
binvalues = array.array('f')
binvalues.read(fileobj, num_lon * num_lat)
data = np.array(binvalues)
data = np.reshape(data, (num_lat, num_lon))
L = [i for i in range(len(data))]
fileobj.close()
plt.plot(L,data[0])
plt.plot(L,data[1])
plt.show()
Do you guys have any lead ? Thank you very much.

import numpy as np
import array
import matplotlib.pyplot as plt
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
num_lon = 128
num_lat = 754
tmpfile = "180523_WT_striatum_#1.dat"
fileobj = open(tmpfile, mode='rb')
fileobj.seek(1020)
binvalues = array.array('f') # 'f' stands for float 4 bytes
# It would be 'd' for float 8 bytes size
binvalues.read(fileobj, 128 * 128 )
data = np.array(binvalues)
data = np.reshape(data, (128,128))
L = np.array([[i for i in range(128)]for j in range(754)])
fileobj.close()
fig = plt.figure()
ax = fig.gca(projection='3d')
for i in range(len(data)):
ax.plot(L[i], data[i], i)
plt.show()

Related

Trying to Plot FFT for an Image Array

I'm trying to create a signal plot for an array of pictures using the following code:
import numpy as np
import sys
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
imgArr = {}
stnArr = {}
frmArr = {}
sgnArr = {}
for i in range(1,2397):
imgArr[i] = mpimg.imread("20210209_themis_rank"+ str(i)+ ".png")
stnArr[i] = np.mean([imgArr[i]]/std(imgArr[i]))
frmArr[i] = i
signal = np.fft.fft(imgArr[i])
for i in range(1,2397):
plt.plot(frmArr,np.abs(signal))
plt.show()
However, I keep on running into the following error. How can I get it to work?
raise ValueError(f"x and y must have same first dimension, but "
ValueError: x and y must have same first dimension, but have shapes (1,) and (600, 600, 4)

Masking a variable with lat and lon but needed 3d array

what i am trying is masking a value from nc file with numpy array, according to specific location but it gives me 1d array and i can not use this array for plotting here my code.
from netCDF4 import Dataset
import matplotlib.pyplot as plt
import numpy as np
import numpy.ma as ma
file = './sample_data/NSS.AMBX.NK.D08214.S0740.E0931.B5312324.WI.nc'
data = Dataset(file,mode='r')
fcdBT89gHz = np.asarray(data.groups['Data_Fields']['fcdr_brightness_temperature_1'][:])
fcdBT150gHz = np.asarray(data.groups['Data_Fields']['fcdr_brightness_temperature_2'][:])
fcdBT183_1gHz = np.asarray(data.groups['Data_Fields']['fcdr_brightness_temperature_3'][:])
fcdBT183_3gHz = np.asarray(data.groups['Data_Fields']['fcdr_brightness_temperature_4'][:])
fcdBT183_7gHz = np.asarray(data.groups['Data_Fields']['fcdr_brightness_temperature_5'][:])
lats = data.groups['Geolocation_Time_Fields']['latitude'] #Enlem degerleri
lons = data.groups['Geolocation_Time_Fields']['longitude'] #Boylam degerleri
latlar = np.asarray(lats[:]) # Lati
lonlar = np.asarray(lons[:]) # Long
lo = ma.masked_outside(lonlar,105,110)
la = ma.masked_outside(latlar,30,35)
merged_coord=~ma.mask_or(la.mask,lo.mask)
h = plt.plot(fcdBT150gHz[merged_coord])
The output is like that but i need latitudes in x axis like this plot
If you need shape of variables:
lo.shape = (2495, 90)
la.shape = (2495, 90)
fcdBT150gHz[merged_coord].shape = (701,)
Maybe i did not use true way for masking. If data is needed here.

Why does plt.plot() plots different graph for a numpy array and a numpy matrix

When I try to plot a graph with matplotlib, I'm unable to plot the numpy array properly but the numpy matrix works, despite the data is the same.
The file is a .dat file. And part of it is like this. I'm sorry that some data with exponential isn't properly displayed:
13.589515189014234 0.15604292500000005
13.735639008250946 0.15257472499999994
13.881762827487661 0.14755997499999998
14.027886646724372 0.14034605000000008
14.174010465961084 0.13002836249999997
14.320134285197797 0.11536830749999996
14.466258104434509 0.09470843482500003
15.343001019854782 -0.29482481522500004
15.489124839091494 -0.41008690550000004
15.635248658328205 -0.50755824292125018
15.781372477564917 -0.55349056577499989
15.927496296801632 -0.52813589407000028
16.073620116038342 -0.44291128949999964
16.219743935275055 -0.33041039448500015
16.365867754511768 -0.22063749432500010
16.511991573748478 -0.12956561664999997
16.658115392985192 -6.2520931050000061E-002
16.804239212221901 -2.0474291900000007E-002
16.950363031458615 -3.3802861749999864E-003
17.096486850695324 -1.1236421675000005E-002
17.242610669932041 -4.4293935437500001E-002
17.388734489168755 -0.10291197632249992
17.534858308405465 -0.18681497748249989
17.680982127642178 -0.29264704324999974
17.827105946878888 -0.40844271439000052
17.973229766115601 -0.50809938749999994
18.119353585352311 -0.55706159005000022
18.265477404589028 -0.53426514450000007
18.411601223825738 -0.44999058192999997
18.557725043062451 -0.33683265428499992
18.703848862299161 -0.22573322450000011
18.849972681535874 -0.13362568075000000
18.996096500772584 -6.6342932249999972E-002
19.142220320009297 -2.4975045235000021E-002
19.288344139246014 -9.3829022500000001E-003
19.434467958482724 -1.9370208699999975E-002
19.580591777719437 -5.4959120624999996E-002
19.726715596956147 -0.11625987367499999
19.872839416192861 -0.20263722292500017
20.018963235429570 -0.30991265800000006
20.165087054666284 -0.42447163175000008
20.311210873902997 -0.51843669877499976
20.457334693139710 -0.55769086224999975
20.603458512376420 -0.52495092840000057
20.749582331613134 -0.43469907825000020
20.895706150849843 -0.32059742052500018
21.041829970086557 -0.21181538367500022
21.187953789323267 -0.12320815802500000
21.334077608559983 -5.9446244649999966E-002
21.480201427796697 -2.1174214224999988E-002
21.626325247033407 -8.1263172499999904E-003
21.772449066270120 -2.0123068274999968E-002
21.918572885506830 -5.7280081410249997E-002
22.064696704743543 -0.11983124174999996
with numpy array:
data = []
for line in open('profile_3.dat'):
new = line.split()
data.append(new)
profile = np.array(data)
plt.figure()
x = profile[:,0]
y = profile[:,1]
plt.plot(x,y)
plt.show()
with numpy matrix:
data = []
for line in open('profile_3.dat'):
new = line.split()
data.append(new)
profile = np.matrix(data)
plt.figure()
x = profile[:,0]
y = profile[:,1]
plt.plot(x,y)
plt.show()
It seems that when plot with numpy array, the graph is inverted and some data is misplaced.
Seems that problem is in strings vs numbers:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
data = []
for line in open('profile_3.dat'):
new = line.split()
data.append(new)
profile = np.array(data)
plt.figure()
x = profile[:,0].astype(np.float)
y = profile[:,1].astype(np.float)
plt.plot(x,y)
plt.show()
Plot for your data:

How can I convert a table of data with different column lengths into boxplots in python

I am Trying to plot an array of data. The following is a sample
34456.11718 34767.75017 34392.43452 34356.77702 34552.49424
34618.99645 34845.01827 34470.82192 34755.43286 34490.34788
34524.72989 34838.92508 34464.9628 34685.11467 34583.76757
34525.16889 34837.37895 34541.02059 34555.63599 34527.23146
34531.52852 34770.05856 34568.93382 34504.1442 34514.08938
34431.45985 34585.67336 34527.43138 34071.39518 34533.3499
34329.05653 34536.24601 34606.97121 34132.64443 34439.45988
34268.17505 34611.81836 34608.9584 34075.29279 34474.64524
34477.37305 34699.84967 34646.87148 33802.50334 34441.68268
34674.54769 34632.93716 34672.11406 33906.01839 34457.02467
34576.99168 34722.83457 34548.2877 34040.83828 34531.64214
34534.72687 34633.32703 34627.64169 34370.23821 34520.28533
34598.89338 34598.50237 34717.49512 34415.73371 34426.95518
34462.53642 34549.27221 34663.26121 34114.69248 34375.88882
34385.24535 34549.24708 34713.14059 33865.1237
34429.79659 34538.31632 34716.97048 34280.39958
34652.65947 34523.53762 34698.31976 34492.3672
34645.35515 34546.5272 34598.81003 34531.15127
34630.22884 34591.32164 34597.6796 34362.6228
34720.29415 34451.27535 34746.00718 34233.68801
34645.84702 34636.53923 34031.19302
34389.24407 34134.58745 34431.07515
The actual array is much longer, but the key feature is it has 5 columns each named in a different text file. Here is my code:
import numpy as np
import matplotlib.pyplot as plt
plt.show()
tube1data = np.genfromtxt("speed1.txt")
tube2data = np.genfromtxt("speed2.txt")
tube3data = np.genfromtxt("speed3.txt")
tube4data = np.genfromtxt("speed4.txt")
tube5data = np.genfromtxt("speed5.txt")
plt.boxplot(tube1data,patch_artist=True)
plt.boxplot(tube2data,patch_artist=True)
plt.boxplot(tube3data,patch_artist=True)
plt.boxplot(tube4data,patch_artist=True)
plt.boxplot(tube5data,patch_artist=True)
plt.show()
The problems is it overlays all of them on one plot
boxplot will happily plot a sequence of data distributions. They don't need to be the same length.
In your case:
plt.boxplot([tube1data, tube2data, <...>], patch_artist=True)
As a more complete example:
import numpy as np
import matplotlib.pyplot as plt
lengths = [100, 10, 200, 20, 50]
dists = [np.random.normal(0, 1, n) for n in lengths]
fig, ax = plt.subplots()
ax.boxplot(dists, patch_artist=True)
plt.show()

Plot really big file in python (5GB) with x axis offset

I am trying to plot a very big file (~5 GB) using python and matplotlib. I am able to load the whole file in memory (the total available in the machine is 16 GB) but when I plot it using simple imshow I get a segmentation fault. This is most probable to the ulimit which I have set to 15000 but I cannot set higher. I have come to the conclusion that I need to plot my array in batches and therefore made a simple code to do that. My main isue is that when I plot a batch of the big array the x coordinates start always from 0 and there is no way I can overlay the images to create a final big one. If you have any suggestion please let me know. Also I am not able to install new packages like "Image" on this machine due to administrative rights. Here is a sample of the code that reads the first 12 lines of my array and make 3 plots.
import os
import sys
import scipy
import numpy as np
import pylab as pl
import matplotlib as mpl
import matplotlib.cm as cm
from optparse import OptionParser
from scipy import fftpack
from scipy.fftpack import *
from cmath import *
from pylab import *
import pp
import fileinput
import matplotlib.pylab as plt
import pickle
def readalllines(file1,rows,freqs):
file = open(file1,'r')
sizer = int(rows*freqs)
i = 0
q = np.zeros(sizer,'float')
for i in range(rows*freqs):
s =file.readline()
s = s.split()
#print s[4],q[i]
q[i] = float(s[4])
if i%262144 == 0:
print '\r ',int(i*100.0/(337*262144)),' percent complete',
i += 1
file.close()
return q
parser = OptionParser()
parser.add_option('-f',dest="filename",help="Read dynamic spectrum from FILE",metavar="FILE")
parser.add_option('-t',dest="dtime",help="The time integration used in seconds, default 10",default=10)
parser.add_option('-n',dest="dfreq",help="The bandwidth of each frequency channel in Hz",default=11.92092896)
parser.add_option('-w',dest="reduce",help="The chuncker divider in frequency channels, integer default 16",default=16)
(opts,args) = parser.parse_args()
rows=12
freqs = 262144
file1 = opts.filename
s = readalllines(file1,rows,freqs)
s = np.reshape(s,(rows,freqs))
s = s.T
print s.shape
#raw_input()
#s_shift = scipy.fftpack.fftshift(s)
#fig = plt.figure()
#fig.patch.set_alpha(0.0)
#axes = plt.axes()
#axes.patch.set_alpha(0.0)
###plt.ylim(0,8)
plt.ion()
i = 0
for o in range(0,rows,4):
fig = plt.figure()
#plt.clf()
plt.imshow(s[:,o:o+4],interpolation='nearest',aspect='auto', cmap=cm.gray_r, origin='lower')
if o == 0:
axis([0,rows,0,freqs])
fdf, fdff = xticks()
print fdf
xticks(fdf+o)
print xticks()
#axis([o,o+4,0,freqs])
plt.draw()
#w, h = fig.canvas.get_width_height()
#buf = np.fromstring(fig.canvas.tostring_argb(), dtype=np.uint8)
#buf.shape = (w,h,4)
#buf = np.rol(buf, 3, axis=2)
#w,h,_ = buf.shape
#img = Image.fromstring("RGBA", (w,h),buf.tostring())
#if prev:
# prev.paste(img)
# del prev
#prev = img
i += 1
pl.colorbar()
pl.show()
If you plot any array with more than ~2k pixels across something in your graphics chain will down sample the image in some way to display it on your monitor. I would recommend down sampling in a controlled way, something like
data = convert_raw_data_to_fft(args) # make sure data is row major
def ds_decimate(row,step = 100):
return row[::step]
def ds_sum(row,step):
return np.sum(row[:step*(len(row)//step)].reshape(-1,step),1)
# as per suggestion from tom10 in comments
def ds_max(row,step):
return np.max(row[:step*(len(row)//step)].reshape(-1,step),1)
data_plotable = [ds_sum(d) for d in data] # plug in which ever function you want
or interpolation.
Matplotlib is pretty memory-inefficient when plotting images. It creates several full-resolution intermediate arrays, which is probably why your program is crashing.
One solution is to downsample the image before feeding it into matplotlib, as #tcaswell suggests.
I also wrote some wrapper code to do this downsampling automatically, based on your screen resolution. It's at https://github.com/ChrisBeaumont/mpl-modest-image, if it's useful. It also has the advantage that the image is resampled on the fly, so you can still pan and zoom without sacrificing resolution where you need it.
I think you're just missing the extent=(left, right, bottom, top) keyword argument in plt.imshow.
x = np.random.randn(2, 10)
y = np.ones((4, 10))
x[0] = 0 # To make it clear which side is up, etc
y[0] = -1
plt.imshow(x, extent=(0, 10, 0, 2))
plt.imshow(y, extent=(0, 10, 2, 6))
# This is necessary, else the plot gets scaled and only shows the last array
plt.ylim(0, 6)
plt.colorbar()
plt.show()

Categories