I am trying to plot a 2D heat map of the function/surface but it is throwing me the type error which I am unable to resolve..
from numbers import Real
from numpy.lib.type_check import real
x = np.linspace(-2,2, num=40, endpoint=True, retstep=False, dtype=None, axis=0)
y = np.linspace(-2,2, num=40, endpoint=True, retstep=False, dtype=None, axis=0)
`
def goldstein_func(x,y):
z = (1+(x+y+1)**2*(19-14*x+3*x**2-14*y+6*x*y+3*y**2))*(30+(2*x-3*y)**2*(18-32*x+12*x**2+48*y-36*x*y+27*y**2))
m = np.array(x,y)
plt.imshow(goldstein_func(x,y), 4)
plt.show()
**The above code throw in an error below:
TypeError Traceback (most recent call last)
in
----> 2 plt.imshow(goldstein_func(x,y), 4)
3 plt.show()
in goldstein_func(x, y)
10 z = (1+(x+y+1)**2*(19-14*x+3*x**2-14*y+6*x*y+3*y**2))*(30+(2*x-3*y)**2*(18-32*x+12*x**2+48*y-36*x*y+27*y**2))
---> 11 m = np.array(x,y)
TypeError: Cannot construct a dtype from an array**
I tried to fix the type-error
It appears that an issue is happening when attempting to construct a NumPy array with np.array(x, y) inside the goldstein_func() function. The np.array() function needs one argument that symbolizes the components of the array or several arguments that symbolizes multiple arrays to be combined. Nevertheless, in your code, you're supplying two independent arguments, x and y, which is producing the TypeError.
To fix the mistake, you can use the np.meshgrid function to create 2-D arrays from the 1-D arrays x and y, and then pass these arrays into the goldstein_func to calculate the matching z values. Here's the adjusted code:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-2, 2, num=40, endpoint=True)
y = np.linspace(-2, 2, num=40, endpoint=True)
X, Y = np.meshgrid(x, y)
def goldstein_func(x, y):
z = (1+(x+y+1)**2*(19-14*x+3*x**2-14*y+6*x*y+3*y**2))*(30+(2*x-3*y)**2*(18-32*x+12*x**2+48*y-36*x*y+27*y**2))
return z
Z = goldstein_func(X, Y)
plt.imshow(Z, cmap='hot', extent=(-2, 2, -2, 2))
plt.show()
I hope this helps you out.
Related
I'm trying to use the contour function of matplotlib.pyplot. I get an error tuple index out of range.
import numpy as np
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt
import math
x, y = make_regression(n_samples=100, n_features=1, noise=10)
y = y + abs(y/2)
thetaInitial = np.random.randn(3,1)
thetaFinal = np.random.randn(3,1)
def f(x): return x**2+x
xmesh, ymesh = np.meshgrid(x, y)
print("x :", xmesh.shape); print("y :", ymesh.shape); print("z: ", z.shape)
z = f(np.array([xmesh, ymesh]))
plt.contour(X=xmesh, Y=ymesh, Z= z, levels=20)
tuple index out of range
There are a few problems that need to be addressed:
Please, read the documentation to obtain contour plots with `help(plt.contour).
from the docs, you'll see that x, y needs to be monotonically sorted. You can achieve that with np.sort(x.reshape(len(x))).
You evaluated your function with z = f(np.array([xmesh, ymesh])), obtaining an array with shape (2, 100, 100). From the docs, Z must be a 2D array. So you have to execute plt.contour(X=xmesh, Y=ymesh, Z=z[0]) or z[1].
I am trying to instantiate a Scipy Interpolate RectBivariateSpline as follows:
import numpy as np
from scipy.interpolate import RectBivariateSpline
x = np.array([1,2,3,4])
y = np.array([1,2,3])
vals = np.array([
[4,1,4],
[4,2,3],
[3,7,4],
[2,4,5]
])
print(x.shape) # (4,)
print(y.shape) # (3,)
print(vals.shape) # (4, 3)
rect_B_spline = RectBivariateSpline(x, y, vals)
However, it returns this error:
Traceback (most recent call last):
File "path/file", line 15, in <module>
rect_B_spline = RectBivariateSpline(x, y, vals)
File "path/file", line 1061, in __init__
ye, kx, ky, s)
dfitpack.error: (my>ky) failed for hidden my: regrid_smth:my=3
Would appreciate any clues as to what the dfitpack error describes and how to resolve.
By default, RectBivariateSpline uses a degree 3 spline. By providing only 3 points along the y-axis it cannot do that. Adding ky=2 to the argument list fixes the problem, as does having more data.
I'm trying to do a simple match filtering operation on a data set in python (so I tried doing conjugation followed by convolution). However, an error message is showing in the convolution function saying object too deep for desired array. Below is the code I'm using:
import numpy as np
import cPickle
import matplotlib.pyplot as plt
with open('meteor2.pkl', 'rb') as f:
data = cPickle.load(f)
vlt = data['vlt']
mfilt=np.conjugate(vlt)
mfilt1=np.convolve(vlt,mfilt,mode='full')
#mfilt=np.conjugate(vlt)
#mfilt1=np.convolve(vlt,mfilt,'same')
r = data['r']
t = data['t']
codes = data['codes']
freqs = data['freqs']
ch0_db = 10*np.log10(np.abs(mfilt1[:, 0, :])**2)
plt.figure()
plt.imshow(ch0_db.T, vmin=0, origin='lower', cmap=plt.cm.coolwarm,aspect='auto')
plt.title('All pulses')
plt.figure()
plt.imshow(ch0_db[3::5, :].T, vmin=0, origin='lower', cmap=plt.cm.coolwarm,aspect='auto')
plt.title('Minimum sidelobe coded-pulses')
plt.show()
np.convolve does one-dimensional convolution, so in this line:
mfilt1=np.convolve(vlt,mfilt,mode='full')
you'll get that error if either vlt or mfilt is not 1-D. For example,
In [12]: x = np.array([[1,2,3]]) # x is 2-D
In [13]: y = np.array([1,2,3])
In [14]: np.convolve(x, y, mode='full')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-14-9bf37a14877a> in <module>()
----> 1 np.convolve(x, y, mode='full')
/home/warren/anaconda/lib/python2.7/site-packages/numpy/core/numeric.pyc in convolve(a, v, mode)
822 raise ValueError('v cannot be empty')
823 mode = _mode_from_name(mode)
--> 824 return multiarray.correlate(a, v[::-1], mode)
825
826 def outer(a,b):
ValueError: object too deep for desired array
It looks like you want 2-D (or higher) convolution. scipy has a few options:
scipy.ndimage.convolve
scipy.signal.convolve
scipy.signal.convolve2d
Basically, is it possible to get scipy.ndimage.map_coordinates to return a multi-valued structure, instead of just a scalar? I'd like to be able to interpolate once to retrieve 5 values at a point, rather than having to interpolate 5 times.
Here's my try at a MWE to demonstrate the problem. I'll start with a 3D interpolation of a scalar. I won't go between points for now because that's not the point.
import numpy as np
from scipy import ndimage
coords = np.array([[1.,1.,1.]])
a = np.arange(3*3*3).reshape(3,3,3)
ndimage.map_coordinates(a,coords.T) # array([13.])
Now, suppose I want a to have pairs of values, not just one. My instinct is
a = np.arange(3*3*3*2).reshape(3,3,3,2)
a[1,1,1] # array([26.,27.])
ndimage.map_coordinates(a[:,:,:],coords.T) # I'd like array([26.,27.])
Instead of the desired output, I get the following:
RuntimeError Traceback (most recent call last)
(...)/<ipython-input-84-77334fb7469f> in <module>()
----> 1 ndimage.map_coordinates(a[:,:,:],np.array([[1.,1.,1.]]).T)
/usr/lib/python2.7/dist-packages/scipy/ndimage/interpolation.pyc in map_coordinates(input, coordinates, output, order, mode, cval, prefilter)
287 raise RuntimeError('input and output rank must be > 0')
288 if coordinates.shape[0] != input.ndim:
--> 289 raise RuntimeError('invalid shape for coordinate array')
290 mode = _extend_mode_to_code(mode)
291 if prefilter and order > 1:
RuntimeError: invalid shape for coordinate array
I can't find a permutation of the shapes of any of the structures (a, coords, etc.) that gives me the answer I'm looking for. Also, if there's a better way to do this than using map_coordinates, go ahead. I thought scipy.interpolate.interp1d might be the way to go but I can't find any documentation or an inkling of what it might do...
That's not possible, I think.
But tensor product interpolation is not difficult:
import numpy as np
from scipy.interpolate import interp1d
def interpn(*args, **kw):
"""Interpolation on N-D.
ai = interpn(x, y, z, ..., a, xi, yi, zi, ...)
where the arrays x, y, z, ... define a rectangular grid
and a.shape == (len(x), len(y), len(z), ...)
"""
method = kw.pop('method', 'cubic')
if kw:
raise ValueError("Unknown arguments: " % kw.keys())
nd = (len(args)-1)//2
if len(args) != 2*nd+1:
raise ValueError("Wrong number of arguments")
q = args[:nd]
qi = args[nd+1:]
a = args[nd]
for j in range(nd):
a = interp1d(q[j], a, axis=j, kind=method)(qi[j])
return a
import matplotlib.pyplot as plt
x = np.linspace(0, 1, 6)
y = np.linspace(0, 1, 7)
k = np.array([0, 1])
z = np.cos(2*x[:,None,None] + k[None,None,:]) * np.sin(3*y[None,:,None])
xi = np.linspace(0, 1, 60)
yi = np.linspace(0, 1, 70)
zi = interpn(x, y, z, xi, yi, method='linear')
plt.subplot(221)
plt.imshow(z[:,:,0].T, interpolation='nearest')
plt.subplot(222)
plt.imshow(zi[:,:,0].T, interpolation='nearest')
plt.subplot(223)
plt.imshow(z[:,:,1].T, interpolation='nearest')
plt.subplot(224)
plt.imshow(zi[:,:,1].T, interpolation='nearest')
plt.show()
I'm using matplotlib. I have a list of 600 values. I also have an polynomial function that I'm graphing with values between 0 and 600. I'm trying to multiply every point by the corresponding value in the list.
I could evaluate the polynomial in a loop, and do the multiplication there, but I would end up with a graph of points instead of a line.
I think I might need to use the Transformations framework, but not sure how to apply it to the graph.
Edit:
a = [5, 2, 3 ... 0, 2, 8] # 600 values
poly_a = polyfit(a)
deriv_a = polyder(poly_a)
b = [232, 342 ... 346, 183] # 600 values
I need to multiply deriv_a by b.
I think you're misunderstanding things a bit. This is what numpy is for (if you're using matplotlib it's already converting things to a numpy array when you plot, regardless.)
Just convert your "list of 600 values" to a numpy array and then evaluate the polynomial.
As an example:
import numpy as np
import matplotlib.pyplot as plt
# Your "list of 600 values"...
x = np.linspace(0, 10, 600)
# Evaluate a polynomial at each location in `x`
y = -1.3 * x**3 + 10 * x**2 - 3 * x + 10
plt.plot(x, y)
plt.show()
Edit:
Based on your edit, it sounds like you're asking how to use numpy.polyder?
Basically, you just want to use numpy.polyval to evaluate the polynomial returned by polyder at your point locations.
To build on the example above:
import numpy as np
import matplotlib.pyplot as plt
# Your "list of 600 values"...
x = np.linspace(0, 10, 600)
coeffs = [-1.3, 10, 3, 10]
# Evaluate a polynomial at each location in `x`
y = np.polyval(coeffs, x)
# Calculate the derivative
der_coeffs = np.polyder(coeffs)
# Evaluate the derivative on the same points...
y_prime = np.polyval(der_coeffs, x)
# Plot the two...
fig, (ax1, ax2) = plt.subplots(nrows=2)
ax1.plot(x, y)
ax1.set_title('Original Function')
ax2.plot(x, y_prime)
ax2.set_title('Deriviative')
plt.show()