I have a 3D numpy array that is a stack of 2D (m,n) images at certain timestamps, t. So my array is of shape (t, m, n). I want to plot the value of one of the pixels as a function of time.
e.g.:
import numpy as np
import matplotlib.pyplot as plt
data_cube = []
for i in xrange(10):
a = np.random(100,100)
data_cube.append(a)
So my (t, m, n) now has shape (10,100,100). Say I wanted a 1D plot the value of index [12][12] at each of the 10 steps I would do:
plt.plot(data_cube[:][12][12])
plt.show()
But I'm getting index out of range errors. I thought I might have my indices mixed up, but every plot I generate seems to be in the 'wrong' axis, i.e. across one of the 2D arrays, but instead I want it 'through' the vertical stack. Thanks in advance!
Here is the solution: Since you are already using numpy, convert you final list to an array and just use slicing. The problem in your case was two-fold:
First: Your final data_cube was not an array. For a list, you will have to iterate over the values
Second: Slicing was incorrect.
import numpy as np
import matplotlib.pyplot as plt
data_cube = []
for i in range(10):
a = np.random.rand(100,100)
data_cube.append(a)
data_cube = np.array(data_cube) # Added this step
plt.plot(data_cube[:,12,12]) # Modified the slicing
Output
A less verbose version that avoids iteration:
data_cube = np.random.rand(10, 100,100)
plt.plot(data_cube[:,12,12])
Related
I have a 2D array of shape 5 and 10. So 5 different arrays with 10 values. I am hoping to get a histogram and see which array is on the lower end versus higher end of a histogram. Hope that makes sense. I am attaching an image of an example of what I mean (labeled example).
Looking for one histogram but the histogram is organized by the distribution of the highest and lowest of each array.
I'm having trouble doing this with Python. I tried a few ways of doing this:
# setting up 2d array
import numpy as np
from scipy import signal
np.random.seed(1234)
array_2d = np.random.random((5,20))
I thought you could maybe just plot all the histograms of each array (5 of them) like this:
for i in range(5):
plt.hist(signal.detrend(array_2d[i,:],type='constant'),bins=20)
plt.show()
And then looking to see which array's histogram is furthest to the right or left, but not sure if that makes too much sense...
Then also considered using .ravel to make the 2D array into a 1D array which makes a nice histogram. But all the values within each array are being shifted around so it's difficult to tell which array is on the lower or higher end of the histogram:
plt.hist(signal.detrend(array_2d.ravel(),type='constant'),bins=20)
plt.xticks(np.linspace(-1,1,10));
How might I get a histogram of the 5 arrays (shape 5, 10) and get the range of the arrays with the lowest values versus array with highest values?
Also please let me know if this is unclear or not possible at all too haha. Thanks!
Maybe you could use a kdeplot? This would replace each input value with a small Gaussian curve and sum them.
from matplotlib import pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
np.random.seed(1234)
array_2d = np.random.random((5, 20))
sns.kdeplot(data=pd.DataFrame(array_2d.T, columns=range(1, 6)), palette='Set1', multiple='layer')
I have an array of variable length filled with 2d coordinate points (coming from a point cloud) which are distributed around (0,0) and i want to convert them into a 2d matrix (=grayscale image).
# have
array = [(1.0,1.1),(0.0,0.0),...]
# want
matrix = [[0,100,...],[255,255,...],...]
how would i achieve this using python and numpy
Looks like matplotlib.pyplot.hist2d is what you are looking for.
It basically bins your data into 2-dimensional bins (with a size of your choice).
here the documentation and a working example is given below.
import numpy as np
import matplotlib.pyplot as plt
data = [np.random.randn(1000), np.random.randn(1000)]
plt.scatter(data[0], data[1])
Then you can call hist2d on your data, for instance like this
plt.hist2d(data[0], data[1], bins=20)
note that the arguments of hist2d are two 1-dimensional arrays, so you will have to do a bit of reshaping of our data prior to feed it to hist2d.
Quick solution using only numpy without the need for matplotlib and therefor plots:
import numpy as np
# given a 2dArray "array" and a desired image shape "[x,y]"
matrix = np.histogram2d(array[:,0], array[:,1], bins=[x,y])
I have multiple 2D arrays saved in a list called image_concat. This list will be composed of over a hundred of these arrays, but for now I'm just trying to make my code run for a list with only two of them. These arrays all have different shapes, and I would like to find the largest x-dimension and largest y-dimension out of all the arrays, and then pad all the other ones with enough zeros around the edges so that in the end, they all have the same shape. Note that the largest x-dimension and largest y-dimension might belong to separate arrays, or they might belong to the same one. What I have tried writing so far is not successfully changing the shape of the smaller array for some reason. But I also think that some issues will arise even after changing the shapes, since some arrays might be off by one in the end due to elements in the shape being even or odd.
import astropy
import numpy as np
import math
import matplotlib.pyplot as plt
from astropy.utils.data import download_file
from astropy.io import fits
images = ['http://irsa.ipac.caltech.edu/ibe/data/wise/allsky/4band_p1bm_frm/9a/02729a/148/02729a148-w2-int-1b.fits?center=89.353536,37.643864deg&size=0.6deg', 'http://irsa.ipac.caltech.edu/ibe/data/wise/allsky/4band_p1bm_frm/2a/03652a/123/03652a123-w4-int-1b.fits?center=294.772333,-19.747157deg&size=0.6deg']
image_list = []
for url in images:
image_list.append(download_file(url, cache=True))
image_concat = [fits.getdata(image) for image in image_list]
# See shapes in the beginning
print(np.shape(image_concat[0]))
print(np.shape(image_concat[1]))
def pad(image_concat):
# Identify largest x and y dimensions
xdims, ydims = np.zeros(len(image_concat)), np.zeros(len(image_concat))
for i in range(len(xdims)):
x, y = np.shape(image_concat[i])
xdims[i] = x
ydims[i] = y
x_max = int(np.max(xdims))
y_max = int(np.max(ydims))
# Pad all arrays except the largest dimensions
for A in image_concat:
x_len, y_len = np.shape(A)
print(math.ceil((y_max-y_len)/2))
print(math.ceil((x_max-x_len)/2))
np.pad(A, ((math.ceil((y_max-y_len)/2), math.ceil((y_max-y_len)/2)), (math.ceil((x_max-x_len)/2), math.ceil((x_max-x_len)/2))), 'constant', constant_values=0)
return image_concat
image_concat = pad(image_concat)
# See shapes afterwards (they haven't changed for some reason)
print(np.shape(image_concat[0]))
print(np.shape(image_concat[1]))
I can't understand why the shape isn't changing for this case. And also, is there a way to easily generalize this so that it will work on many arrays regardless of if they have even or odd dimensions?
np.pad doesn't modify the array in-place, it returns a padded array. So you'd need to do image_concat[i] = np.pad(...), where i is the index of A.
I am new to machine learning. I was teaching myself data visualization with MATPLOTLIB. my code is pretty simple.
It takes a numpy array (x = np.random.rand(1,100)) of shape=(1, 100)).
It converts numpy array x into y(y = np.sin(x)).
Final task is to visualise this in a BAR(plt.bar(x, y, label="BAR", color='r'))
But it is throwing VALUE ERROR.Even though there are already answers to this question, but none seems to work so far for me.
In one answer for this question By unutbu
he explains that this error is raised "whenever one tries to evaluate an array in boolean context".
I am unable to understand how I am using these arrays as boolean?
MY CODE:
import matplotlib.pyplot as plt
import numpy as np
#arguments are shape: 1=row; 100=columns
x = np.random.rand(1, 100)
y = np.cos(x)
#bars
plt.bar(x, y, label='Bars1', color='pink')
#legends
plt.legend()
#show the figure
plt.show()
You need to replace
x = np.random.rand(1, 100)
with
x = np.random.rand(100)
The reason is that the former gives you an array of arrays (with one array inside, but it is still a 2D array overall with dimensions 1-by-100), while the latter gives you a 1D array (of length 100). In order to visualize it with plt, you need the latter.
Let's say I have a row vector with the shape (1, 100). Call it row.
I want to display its values in a line plot. The x-axis displays the vector indices. The y-axis displays the values at the corresponding indices. How would you do it in matplotlib?
EDIT:
Here is what I have tried:
indices = [n for n in range(100)]
values = list(row[:, :100])
pyplot.plot(indices, values)
The array indices is not necessary.
The values array syntax is unclear... and an error in python, unless you are using numpy.
The following will plot an array of random values, with indices as x and the random numbers stored in values as y
import matplotlib.pyplot as plt
import random
# indices = [n for n in range(100)]
values = [random.random() for _ in range(100)]
plt.plot(values)
plt.show()
import matplotlib.pyplot as plt
indices = range(100) # already returns a list, no need to iterate again
values = # insert 1d vector here, what you seem to use is multi-dim
plt.plot(indices, values)
plt.show()