plotting a list of arrays with matplotlib - python

I have a list raws of arrays that I would like to plot in ipython notebook. Here is the code I am trying to get working:
fig, axes = subplots(len(raws),1, sharex=True, tight_layout=True, figsize=(12, 6), dpi=72)
for r in range(len(raws)):
axes[r].plot(raws)
I've been lost for hours if not days trying to figure out how to index the list raws, such that I can plot each mxn array on it's own axis where n is the number of time points, i.e., x-axis and m is the number of time-series functions sampled at each point.
When I code:
for r in range(len(raws)):
axes[r].plot(raws[r])
I get an ValueError: setting an array element with a sequence.
For your information:
len(raws) = 2
type(raws) = 'list'
np.shape(raws[0][0]) = (306, 10001)
raws =
[(array([[ -4.13211217e-12, -4.13287303e-12, -4.01705259e-12, ...,
1.36386023e-12, 1.65182851e-12, 2.00368966e-12],
[ 1.08914129e-12, 1.47828466e-12, 1.82257607e-12, ...,
-2.70151520e-12, -2.48631967e-12, -2.28625548e-12],
[ -7.80962369e-14, -1.27119591e-13, -1.73610315e-13, ...,
-1.13219629e-13, -1.15031720e-13, -1.12106621e-13],
...,
[ 2.52774254e-12, 2.32293195e-12, 2.02644002e-12, ...,
4.20064191e-12, 3.94858906e-12, 3.69495394e-12],
[ -4.38122146e-12, -4.96229676e-12, -5.47782145e-12, ...,
3.93820033e-12, 4.18850823e-12, 4.34950629e-12],
[ -1.07284424e-13, -9.23447993e-14, -7.89852400e-14, ...,
7.92079631e-14, 5.60172215e-14, 3.04448868e-14]]), array([ 60. , 60.001, 60.002, ..., 69.998, 69.999, 70. ])), (array([[ -6.71363108e-12, -5.80501003e-12, -4.95944514e-12, ...,
-3.25087343e-12, -2.68982494e-12, -2.13637448e-12],
[ -5.04818633e-12, -4.65757005e-12, -4.16084140e-12, ...,
-4.26120531e-13, 2.20744290e-13, 7.81245614e-13],
[ 1.97329506e-13, 1.64543867e-13, 1.32679812e-13, ...,
2.11645494e-13, 1.94795729e-13, 1.75781773e-13],
...,
[ 3.04245661e-12, 2.28376461e-12, 1.54118900e-12, ...,
-1.14020908e-14, -8.04647589e-13, -1.52676489e-12],
[ -1.83485962e-13, -5.22949893e-13, -8.60038852e-13, ...,
7.70312553e-12, 7.20825156e-12, 6.58362857e-12],
[ -7.26357906e-14, -7.11700989e-14, -6.88759767e-14, ...,
-1.04171843e-13, -1.03084861e-13, -9.68462427e-14]]), array([ 60. , 60.001, 60.002, ..., 69.998, 69.999, 70. ]))]

Just so I can post code, I am responding here.
Looks like your data is nested in the form
[ ( array1, array2, ..., arrayN ) ]
This could be handled in one of two ways:
In [2]: raws = [np.random.rand(20, 100), np.random.rand(20, 100)]
In [3]: raws = raws[0]
In [4]: f, axes = plt.subplots(len(raws), 1)
In [5]: for i in range(len(raws)):
...: axes[i].plot(raws[i])
Or
In [3]: raws = [(np.random.rand(20, 100), np.random.rand(20, 100))]
In [4]: f, axes = plt.subplots(len(raws[0]), 1)
In [5]: for i in range(len(raws[0])):
...: axes[i].plot(raws[0][i])

If you have a list of arrays such as abac below, you can plot as following:
import numpy as np
a = np.array(range(20))
b = a * 2
c = a * 3
abac = a,b,a,c
plt.plot(*abac)

Related

Empty 2d histogram, plotly

I use this code:
import plotly.plotly as py
import plotly.graph_objs as go
import numpy as np
z = []
c = []
for i in range(0,100,2):
z.append(embedding[i])
c.append(embedding2[i])
x = np.asarray(z)
y = np.asarray(c)
print (x)
print (y)
data = [
go.Histogram2d(
x=x,
y=y
)
]
py.iplot(data)
Embeddings are two np.ndarray with shape (10242,10242). The data is passed to the histogram, below is x and y printed out. The loop is just to reduce the data for this test.
[[ -1.07009469e-03 -4.14190844e-05 2.83694127e-05 ..., 3.80232710e-49 1.11805697e-48 1.35691326e-49]
[ -2.51900739e-04 -1.24530108e-04 1.06271439e-04 ..., -1.70912532e-49 3.49318016e-49 -6.71164371e-50]
[ 4.75347102e-04 -2.99087401e-04 7.38855263e-06 ..., -1.77945437e-50 2.50268997e-49 1.32159499e-49]
...,
[ 7.19245324e-05 3.62139711e-06 6.79869681e-05 ..., 9.24108834e-37 2.77809808e-36 -1.77212812e-36]
[ 1.49892464e-04 8.55360952e-05 8.07507441e-05 ..., -4.85739967e-49 3.32748802e-49 -1.22085056e-49]
[ 3.94947451e-05 -7.60262599e-05 -1.83208907e-05 ..., 7.93846393e-50 3.08010941e-50 8.93558373e-51]]
[[ -1.07009469e-03 -4.14190844e-05 2.83694127e-05 ..., 3.80232710e-49 1.11805697e-48 1.35691326e-49]
[ -2.51900739e-04 -1.24530108e-04 1.06271439e-04 ..., -1.70912532e-49 3.49318016e-49 -6.71164371e-50]
[ 4.75347102e-04 -2.99087401e-04 7.38855263e-06 ..., -1.77945437e-50 2.50268997e-49 1.32159499e-49]
...,
[ 7.19245324e-05 3.62139711e-06 6.79869681e-05 ..., 9.24108834e-37 2.77809808e-36 -1.77212812e-36]
[ 1.49892464e-04 8.55360952e-05 8.07507441e-05 ..., -4.85739967e-49 3.32748802e-49 -1.22085056e-49]
[ 3.94947451e-05 -7.60262599e-05 -1.83208907e-05 ..., 7.93846393e-50 3.08010941e-50 8.93558373e-51]]
But produced output is empty:
Why does this happen? And how can I display the data?

Making a multidimensional list of vectors

I am quite new to Python so bear with me. I am writing a program to calculate some physical quantity, let's call it A. A is a function of several variables, let's call them x, y, z. So I have three nested loops to calculate A for the values of x, y, z that I am interested in.
for x in xs:
for y in ys:
for z in zs:
A[x, y, z] = function_calculating_value(x,y,z)
Now, the problem is that A[x,y,z] is two-dimensional array containing both the mean value and the variance so that A[x,y,z] = [mean, variance]. From other languages I am used to initializing A using function similar to np.zeros(). How do I do that here? What is the easiest way to achieve what I want, and how do I access the mean and variance easily for a given (x,y,z)?
(the end goal is to be able to plot the mean with the variance as error bars, so if there is an even more elegant way of doing this, I appreciate that as well)
thanks in advance!
You can create and manipulate your multi-dimensional array with numpy
# Generate a random 4d array that has nx = 3, ny = 3, and nz = 3, with each 3D point having 2 values
mdarray = np.random.random( size = (3,3,3,2) )
# The overall shape of the 4d array
mdarray
Out[66]:
array([[[[ 0.80091246, 0.28476668],
[ 0.94264747, 0.27247111],
[ 0.64503087, 0.13722768]],
[[ 0.21371798, 0.41006764],
[ 0.79783723, 0.02537987],
[ 0.80658387, 0.43464532]],
[[ 0.04566927, 0.74836831],
[ 0.8280196 , 0.90288647],
[ 0.59271082, 0.65910184]]],
[[[ 0.82533798, 0.29075978],
[ 0.76496127, 0.1308289 ],
[ 0.22767752, 0.01865939]],
[[ 0.76849458, 0.7934015 ],
[ 0.93313128, 0.88436557],
[ 0.06897508, 0.00307739]],
[[ 0.15975812, 0.00792386],
[ 0.40292818, 0.21209199],
[ 0.48805502, 0.71974702]]],
[[[ 0.66522525, 0.49797465],
[ 0.29369336, 0.68743839],
[ 0.46411967, 0.69547356]],
[[ 0.50339875, 0.66423777],
[ 0.80520751, 0.88115054],
[ 0.08296022, 0.69467829]],
[[ 0.76572574, 0.45332754],
[ 0.87982243, 0.15773385],
[ 0.5762041 , 0.91268172]]]])
# Both values for this specific sample at x = 0, y = 1 and z = 2
mdarray[0,1,2]
Out[67]: array([ 0.80658387, 0.43464532])
mdarray[0,1,2,0] # mean only at the same point
Out[68]: 0.8065838666297338
mdarray[0,1,2,1] # variance only at the same point
Out[69]: 0.43464532443865489
You can also get only the means or the variance values separately by slicing the array:
mean = mdarray[:,:,:,0]
variance = mdarray[:,:,:,1]
mean
Out[74]:
array([[[ 0.80091246, 0.94264747, 0.64503087],
[ 0.21371798, 0.79783723, 0.80658387],
[ 0.04566927, 0.8280196 , 0.59271082]],
[[ 0.82533798, 0.76496127, 0.22767752],
[ 0.76849458, 0.93313128, 0.06897508],
[ 0.15975812, 0.40292818, 0.48805502]],
[[ 0.66522525, 0.29369336, 0.46411967],
[ 0.50339875, 0.80520751, 0.08296022],
[ 0.76572574, 0.87982243, 0.5762041 ]]])
I'm still unsure how I would have preferred to plot this data, will think about this a bit and update this answer.

Why does matplotlib extrapolate/plot missing values?

I have a situation where sometimes, a whole series of data is not available. I'm real-time plotting values from sensors, and these can be turned on and off via user interaction, and thus I cannot be sure the values are always in a series. A user can start a sensor and later turn it off and on again, but In this case, matplotlib draws a line from the last end point and the new start point.
The data I plotted was as follows:
[[ 5. 22.57011604]
[ 6. 22.57408142]
[ 7. 22.56350136]
[ 8. 22.56394005]
[ 9. 22.56790352]
[ 10. 22.56451225]
[ 11. 22.56481743]
[ 12. 22.55789757]
#Missing x vals. Still plots straight line..
[ 29. 22.55654716]
[ 29. 22.56066513]
[ 30. 22.56110382]
[ 31. 22.55050468]
[ 32. 22.56550789]
[ 33. 22.56213379]
[ 34. 22.5588932 ]
[ 35. 22.54829407]
[ 35. 22.56697655]
[ 36. 22.56005478]
[ 37. 22.5568161 ]
[ 38. 22.54621696]
[ 39. 22.55033493]
[ 40. 22.55079269]
[ 41. 22.55475616]
[ 41. 22.54783821]
[ 42. 22.55195618]]
my plot function looks a lot simplified like this:
def plot(self, data)
for name, xy_dict in data.iteritems():
x_vals = xy_dict['x_values']
y_vals = xy_dict['y_values']
line_to_plot = xy_dict['line_number']
self.lines[line_to_plot].set_xdata(x_vals)
self.lines[line_to_plot].set_ydata(y_vals)
Does anyone know why it does like that? And do I have to take care of non-serial x and y values when plotting? It seems matplotlib should take care of this on its own.. Otherwise i have to split lists into smaller lists and plot these?
One option would be to add dummy items wherever data is missing (in your case apparently when x changes by more than 1), and set them as masked elements. That way matplotlib skips the line segments. For example:
import numpy as np
import matplotlib.pylab as pl
# Your data, with some additional elements deleted...
data = np.array(
[[ 5., 22.57011604],
[ 6., 22.57408142],
[ 9., 22.56790352],
[ 10., 22.56451225],
[ 11., 22.56481743],
[ 12., 22.55789757],
[ 29., 22.55654716],
[ 33., 22.56213379],
[ 34., 22.5588932 ],
[ 35., 22.54829407],
[ 40., 22.55079269],
[ 41., 22.55475616],
[ 41., 22.54783821],
[ 42., 22.55195618]])
x = data[:,0]
y = data[:,1]
# Difference from element to element in x
dx = x[1:]-x[:-1]
# Wherever dx > 1, insert a dummy item equal to -1
x2 = np.insert(x, np.where(dx>1)[0]+1, -1)
y2 = np.insert(y, np.where(dx>1)[0]+1, -1)
# As discussed in the comments, another option is to use e.g.:
#x2 = np.insert(x, np.where(dx>1)[0]+1, np.nan)
#y2 = np.insert(y, np.where(dx>1)[0]+1, np.nan)
# and skip the masking step below.
# Mask elements which are -1
x2 = np.ma.masked_where(x2 == -1, x2)
y2 = np.ma.masked_where(y2 == -1, y2)
pl.figure()
pl.subplot(121)
pl.plot(x,y)
pl.subplot(122)
pl.plot(x2,y2)
Another option is to include None or numpy.nan as values for y.
This, for example, shows a disconnected line:
import matplotlib.pyplot as plt
plt.plot([1,2,3,4,5],[5,6,None,7,8])
Matplotlib will connect all your consequetive datapoints with lines.
If you want to avoid this you could split your data at the missing x-values, and plot the two splitted lists separately.

Python: matrix-vector multiplication with broadcasting

I have a numpy 2x2 matrix defined as follows:
a = np.pi/2
g = np.asarray([[-np.sin(a), -np.cos(a)],
[ np.cos(a), -np.sin(a)]])
Now, I have numpy array of 2D points that I would like to transform using this matrix. So we can simulate a bunch (25) of 2D points as follows:
p = np.random.rand(25, 2)
How can I do this matrix-vector multiplication for all these 25 points with broadcasting rather than do a for loop?
At the moment, I can do something like:
for i in range(25):
print np.dot(g, p[i])
This should give me another 2D array with the shape (25, 2).
Is there a more elegant way to do this without the for loop?
I think what you want is -
np.dot(p,g.T)
.T is to transpose an array
Example/Demo -
In [1]: import numpy as np
In [2]: a = np.pi/2
In [3]: g = np.asarray([[-np.sin(a), -np.cos(a)],
...: [ np.cos(a), -np.sin(a)]])
In [4]: p = np.random.rand(25, 2)
In [8]: for i in range(25):
...: print(np.dot(g, p[i]))
...:
[-0.56997282 -0.70151323]
[-0.65807814 -0.21773391]
[-0.533987 -0.53936287]
[-0.91982277 -0.01423868]
[-0.96648577 -0.42122831]
[-0.67169383 -0.94959473]
[-0.09013282 -0.57637376]
[-0.03937037 -0.94635173]
[ -2.59523258e-01 -4.04297667e-05]
[-0.77029438 -0.67325988]
[-0.24862373 -0.89806226]
[-0.91866799 -0.07927881]
[-0.83540497 -0.33473515]
[-0.38738641 -0.75406194]
[-0.07569734 -0.66859275]
[-0.72707983 -0.21314985]
[-0.67738699 -0.90763549]
[-0.96172981 -0.68684667]
[-0.40152064 -0.14629421]
[-0.46495457 -0.37456133]
[-0.97915149 -0.0470546 ]
[-0.76488223 -0.70756525]
[-0.21534494 -0.91354898]
[-0.25035908 -0.37841355]
[-0.17990176 -0.18436497]
In [10]: np.dot(p,g.T)
Out[10]:
array([[ -5.69972820e-01, -7.01513225e-01],
[ -6.58078138e-01, -2.17733909e-01],
[ -5.33987004e-01, -5.39362872e-01],
[ -9.19822767e-01, -1.42386768e-02],
[ -9.66485769e-01, -4.21228314e-01],
[ -6.71693832e-01, -9.49594730e-01],
[ -9.01328234e-02, -5.76373760e-01],
[ -3.93703749e-02, -9.46351732e-01],
[ -2.59523258e-01, -4.04297667e-05],
[ -7.70294378e-01, -6.73259882e-01],
[ -2.48623728e-01, -8.98062260e-01],
[ -9.18667987e-01, -7.92788080e-02],
[ -8.35404971e-01, -3.34735152e-01],
[ -3.87386412e-01, -7.54061939e-01],
[ -7.56973425e-02, -6.68592746e-01],
[ -7.27079833e-01, -2.13149846e-01],
[ -6.77386988e-01, -9.07635490e-01],
[ -9.61729810e-01, -6.86846673e-01],
[ -4.01520636e-01, -1.46294211e-01],
[ -4.64954574e-01, -3.74561327e-01],
[ -9.79151491e-01, -4.70545953e-02],
[ -7.64882230e-01, -7.07565246e-01],
[ -2.15344940e-01, -9.13548984e-01],
[ -2.50359076e-01, -3.78413552e-01],
[ -1.79901758e-01, -1.84364974e-01]])
Try:
np.dot(p, g.T)
which multiplies the points by the transpose of the rotation matrix.

Numpy: Avoiding nested loops to operate on matrix-valued images

I am a beginner at python and numpy and I need to compute the matrix logarithm for each "pixel" (i.e. x,y position) of a matrix-valued image of dimension NxMx3x3. 3x3 is the dimensions of the matrix at each pixel.
The function I have written so far is the following:
def logm_img(im):
from scipy import linalg
dimx = im.shape[0]
dimy = im.shape[1]
res = zeros_like(im)
for x in range(dimx):
for y in range(dimy):
res[x, y, :, :] = linalg.logm(asmatrix(im[x,y,:,:]))
return res
Is it ok?
Is there a way to avoid the two nested loops ?
Numpy can do that. Just call numpy.log:
>>> import numpy
>>> a = numpy.array(range(100)).reshape(10, 10)
>>> b = numpy.log(a)
__main__:1: RuntimeWarning: divide by zero encountered in log
>>> b
array([[ -inf, 0. , 0.69314718, 1.09861229, 1.38629436,
1.60943791, 1.79175947, 1.94591015, 2.07944154, 2.19722458],
[ 2.30258509, 2.39789527, 2.48490665, 2.56494936, 2.63905733,
2.7080502 , 2.77258872, 2.83321334, 2.89037176, 2.94443898],
[ 2.99573227, 3.04452244, 3.09104245, 3.13549422, 3.17805383,
3.21887582, 3.25809654, 3.29583687, 3.33220451, 3.36729583],
[ 3.40119738, 3.4339872 , 3.4657359 , 3.49650756, 3.52636052,
3.55534806, 3.58351894, 3.61091791, 3.63758616, 3.66356165],
[ 3.68887945, 3.71357207, 3.73766962, 3.76120012, 3.78418963,
3.80666249, 3.8286414 , 3.8501476 , 3.87120101, 3.8918203 ],
[ 3.91202301, 3.93182563, 3.95124372, 3.97029191, 3.98898405,
4.00733319, 4.02535169, 4.04305127, 4.06044301, 4.07753744],
[ 4.09434456, 4.11087386, 4.12713439, 4.14313473, 4.15888308,
4.17438727, 4.18965474, 4.20469262, 4.21950771, 4.2341065 ],
[ 4.24849524, 4.26267988, 4.27666612, 4.29045944, 4.30406509,
4.31748811, 4.33073334, 4.34380542, 4.35670883, 4.36944785],
[ 4.38202663, 4.39444915, 4.40671925, 4.41884061, 4.4308168 ,
4.44265126, 4.4543473 , 4.46590812, 4.47733681, 4.48863637],
[ 4.49980967, 4.51085951, 4.52178858, 4.53259949, 4.54329478,
4.55387689, 4.56434819, 4.57471098, 4.58496748, 4.59511985]])

Categories

Resources