Zipping coordinates and then accessing them - python

I have a three vectors of x,y,z coordinates, something like
x = [1,2,3,4,5]
y = [6,7,8,9,10]
z = [11,12,13,14,15]
I want to zip them to have an 5x3 array of coordinates. But when I do
coords = zip(x,y,z)
and then try to print coords, I get
and I cannot plot them either,
How can I get 5x3 array?

You can use numpy function directly:
np.array(list(zip(x,y,z)))
If you didn't import numpy:
import numpy as np

call list on the zip object or use it in a list comprehension.

Related

How to unpack and reshape a list of arrays when passing it as function parameter in Python

When I run the following code
import numpy as np
x = np.random.rand(100, 2)
rv_values, bins_values = np.histogramdd(x, bins=100, density=True)
meshed_coordinates = np.meshgrid(*bins_values)
the meshed_coordinates variables becomes a list or two arrays of dimension (101,101).
This is not a surprise since passing bins=100 to np.histogramdd in the example returns the list bins_values which contains two 1D arrays of length 101.
I want to use the operator * in np.meshgrid(*bins_values) in such a way it passes the list bins_values with shortened arrays, for example bins_values[0][:-1] and bins_values[1][:-1], without the need of shorten them one by one outside the function call (or, for arbitrary lengths of the list, by resorting to a for loop that shorten each array in the list outside the function call).
you may use the center of each bin?
import numpy as np
x = np.random.rand(100, 2)
rv_values, bins_values = np.histogramdd(x, bins=100, density=True)
bins_values[0] = (bins_values[0][:-1] + bins_values[0][1:])/2
bins_values[1] = (bins_values[1][:-1] + bins_values[1][1:])/2
meshed_coordinates = np.meshgrid(*bins_values)

Mapping array into higher-dimension - Python

I've to map R^2 array X=[x1, x2] into R^3 array X'=[x1, x2, x1^2].
Is there any compact solution?
ADDED: My starting array is a numpy array e.g. x = numpy.array([2, 3]). I want to end up with another numpy array e.g. x' = numpy.array([2, 3, 4]).
For the case where your array is a numpy array with shape (2,), one way to add the additional member is
xx = numpy.append(x, x[0]**2)
Unfortunately, if you try something like x + [x[0]**2] numpy will add the elements together rather than append the new element. If you try something like [x[0], x[1], x[0]**2] you end up with a list rather than a numpy array.

Drawing points with matplotlib

I have a list of points in the form of
points=[(x1,y1),...(xn,yn)...]
I am looking for a pythonic way to transform the list into
x=[x1,...xn] y=[y1,...yn]
One way to do it would be
x = map (lambda x: x[1],points)
However, maybe there is a more pythonic way to directly draw from "points" mentioned above?
You can do something like this:
x = []
y = []
for point in points:
x.append(point[0])
y.append(point[1])
or:
x,y = [i[0] for i in points], [i[1] for i in points]
but the best way is to use zip:
x,y = zip(*points)
zip is better than map and it is faster, you should define a function in map with lambda. so I think the best way to do this is with zip.
In addition to mehrdad-pedramfar answer:
If using numpy is not a problem you can convert your list of tuples to a numpy array and then just use indexing.
import numpy as np
short_example = np.array([(1,2),(2,4),(4,6)])
short_example[:,0]
gives a numpy array of all x values:
array([1, 2, 4])
short_example[:,1]
gives a numpy array of all y values:
array([2, 4, 6])

NxN python arrays subsets

I need to carry out some operation on a subset of an NxN array. I have the center of the sub-array, x and y, and its size.
So I can easily do:
subset = data[y-size:y+size,x-size:x+size]
And this is fine.
What I ask is if there is the possibility to do the same without writing an explicit loop if x and y are both 1D arrays of positions.
Thanks!
Using a simple example of a 5x5 array and setting size=1 we can get:
import numpy as np
data = np.arange(25).reshape((5,5))
size = 1
x = np.array([1,4])
y = np.array([1,4])
subsets = [data[j-size:j+size,i-size:i+size] for i in x for j in y]
print(subsets)
Which returns a list of numpy arrays:
[array([[0, 1],[5, 6]]),
array([[15, 16],[20, 21]]),
array([[3, 4],[8, 9]]),
array([[18, 19],[23, 24]])]
Which I hope is what you are looking for.
To get the list of subset assuming you have the list of positions xList and yList, this will do the tric:
subsetList = [ data[y-size:y+size,x-size:x+size] for x,y in zip(xList,yList) ]

Plotting a heat map from three lists: X, Y, Intensity

I don't get how to create a heatmap (or contour plot) when I have x, y, intensity. I have a file which looks like this:
0,1,6
0,2,10
....
So far:
with open('eye_.txt', 'r') as f:
for line in f:
for word in line.split():
l = word.strip().split(',')
x.append(l[0])
y.append(l[1])
z.append(l[2])
Tried using pcolormesh but it wants a shape object and I'm unsure how to convert these lists into a NumPy array.
I tried:
i,j = np.meshgrid(x,y)
arr = np.array(z)
plt.pcolormesh(i,j,arr)
plt.show()
It tells me that:
IndexError: too many indices
Can someone stop me from bashing my head against a keyboard, please?
OK, there's a few steps to this.
First, a much simpler way to read your data file is with numpy.genfromtxt. You can set the delimiter to be a comma with the delimiter argument.
Next, we want to make a 2D mesh of x and y, so we need to just store the unique values from those to arrays to feed to numpy.meshgrid.
Finally, we can use the length of those two arrays to reshape our z array.
(NOTE: This method assumes you have a regular grid, with an x, y and z for every point on the grid).
For example:
import matplotlib.pyplot as plt
import numpy as np
data = np.genfromtxt('eye_.txt',delimiter=',')
x=data[:,0]
y=data[:,1]
z=data[:,2]
## Equivalently, we could do that all in one line with:
# x,y,z = np.genfromtxt('eye_.txt', delimiter=',', usecols=(0,1,2))
x=np.unique(x)
y=np.unique(y)
X,Y = np.meshgrid(x,y)
Z=z.reshape(len(y),len(x))
plt.pcolormesh(X,Y,Z)
plt.show()
In case you don't have a regular grid (i.e. a value of z for each meshgrid value of x and y), you can use a more general method based on pandas data frames:
import pandas as pd
import seaborn as sns
import matplotlib.pypot as plt
data = pd.DataFrame(data={'x':x, 'y':y, 'z':z})
data = data.pivot(index='x', columns='y', values='z')
sns.heatmap(data)
plt.show()
The pivot method will use unique values from index and columns to construct a table with missing measurments set to NaN. The table can then be plotted as a heatmap.
The index error arises from the fact that pcolormesh expects a 2D array while your arr is a 1D vector. Also if I understand correctly, your input file has the form
0,1,z
0,2,z
...
0,ymax,z
...
1,1,z
1,2,z
...
xmax,ymax,z
In that case meshgrid(x,y) will not work as it expects something like meshgrid(range(xmax),range(ymax)) i.e. vectors without repeated values.
In your case you need to find out how many distinct x and y values there are and then simply reshape your vectors into 2D arrays.
shape = np.unique(x).shape[0],np.unique(y).shape[0]
x_arr = x.reshape(shape)
y_arr = y.reshape(shape)
z_arr = z.reshape(shape)
plt.pcolormesh(x_arr,y_arr,z_arr)
To convert a list into a numpy array you can use np.asarray.
Here's an easy way to get a heatmap, you should be able to adapt this example to your problem.
import matplotlib.pyplot as plt
import numpy as np
a = [[1,2,3], [3,4,5], [5,6,7], [7, 8, 9]]
b = np.asarray(a)
plt.pcolor(b)
plt.show()
To read the data in like a list of lists you can do:
a = []
for line in file.readlines():
a.append( map( int, line.split(',') ) )
in short. In a longer version it's the equivalent of:
a = []
for line in file.readlines():
tmp = line.split(',')
inttmp = [int(x) for x in a]
a.append(inttmp)

Categories