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].
Related
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.
import numpy as np
x = ['0.01107', '0.02314', '0.03321', '0.04428', '0.08035']
y = ['0.8864', '0.6703', '0.4542', '0.3382', '0.2321']
hypotenuse_array = np.hypot(x, y)
print("Hypotenuse_array = ", hypotenuse_array)
Doesn't work because of float I think?
a_zip = zip(x, y)
zipped = list(a_zip)
print(zipped)
How to pass X & Y zipped list to np.hypot on loop?
I think the first issue is that you are using strings in the arrays of x and y. If you try to use numbers whith the following code, it will produce a result. But I am not sure if that is what you want to achieve though.
import numpy as np
x = [0.01107, 0.02314, 0.03321, 0.04428, 0.08035]
y = [0.8864, 0.6703, 0.4542, 0.3382, 0.2321]
hypotenuse_array = np.hypot(x, y)
print("Hypotenuse_array = ", hypotenuse_array)
Convert string arrays to float.
import numpy as np
x = ['0.01107', '0.02314', '0.03321', '0.04428', '0.08035']
y = ['0.8864', '0.6703', '0.4542', '0.3382', '0.2321']
# convert x & y to numpy float as we pass them to hypot
hypotenuse_array = np.hypot(np.array(x).astype(np.float), np.array(y).astype(np.float))
print("Hypotenuse_array = ", hypotenuse_array)
# Output: array([0.88646912, 0.6706993 , 0.4554125 , 0.34108644, 0.2456146 ])
So I made my list but after that I don't know how to take out of it my x and y so I can use it later to create a graph
import random
import numpy as np
import matplotlib.pyplot as plt
tabuletson = []
for i in range(0, 10):
x = round(random.uniform(-1000,1000),2)
y = (2*x+1)
tabuletson.append([x,y])
print(tabuletson)
wielomian = np.poly1d(np.polyfit(x,y,3))
linia = np.linspace(-2000,2000,2000)
plt.scatter(x,y)
plt.plot(linia,wielomian(linia))
plt.show()
All you have to do is to add one line of code after and outside your for loop. This command will create two lists containing x and y values. You can use the same variable names x and y.
x, y = zip(*tabuletson)
I think that this is a better way to do what you want according of how plt.scatter and plt.plot work. Hope it works as you want!
import random
import numpy as np
import matplotlib.pyplot as plt
x = []; y = []
for i in range(10):
x.append(round(random.uniform(-1000,1000),2))
y.append(2*x[i]+1)
wielomian = np.poly1d(np.polyfit(x,y,3))
linia = np.linspace(-2000,2000,2000)
plt.scatter(x,y)
plt.plot(linia,wielomian(linia))
plt.show()
The np.polyfit and plt.scatter functions you are using require separate lists of X and Y coordinates.
Try:
import random
import numpy as np
import matplotlib.pyplot as plt
tabuletson_x = []
tabuletson_y = []
for i in range(0, 10):
x = round(random.uniform(-1000,1000),2)
y = (2*x+1)
tabuletson_x.append(x)
tabuletson_y.append(y)
print(tabuletson_x)
print(tabuletson_y)
wielomian = np.poly1d(np.polyfit(tabuletson_x,tabuletson_y,3))
linia = np.linspace(-2000,2000,2000)
plt.scatter(tabuletson_x,tabuletson_y)
plt.plot(linia,wielomian(linia))
plt.show()
Note: referencing x and y after the for cycle will give you the last values from the randomly generated list:
list of x vals: [-8.78, 554.81, -693.22, 955.8, 88.95, 235.55, -108.67, -804.08, 494.65, 754.58]
list of y vals: [-16.56, 1110.62, -1385.44, 1912.6, 178.9, 472.1, -216.34, -1607.16, 990.3, 1510.16]
x: 754.58
y: 1510.16
For more info:
PyPlot Scatter documentation
PolyFit documentation
Your x and y are stored in your list tabuletson. Like this: [[x0,y0], [x1,y1], ..., [x,y]]
So you can, for example, get the value of x1 and y1 with x1 = tabuletson[1][0] and y1 = tabuletson[1][1]
Is that your question ?
tabuletson = np.array(tabuletson)
X, Y = tabuletson[:,0], tabuletson[:,1]
X will have all your xs from list
And, Y will have all your ys from list
y_boxes_1 = [y[i:i + divisor_1] for i in range(0, len(y), divisor_1)]
x_boxes_1 = [x[i:i + divisor_1] for i in range(0, len(x), divisor_1)]
The above code divides a list by a divisor. What I want to do is use numpy polyfit to create a new list of polynomial coefficients for each individual box of y and box of x.
If:
x_boxes_1 = [[1,2,3,4,5,6,7,8],[9,10,11,12,13,14,15,16]]
y_boxes_1 = [[3,5,2,3,1,2,3,4],[2,3,4,1,5,6,7,10]]
Then polyfit would use only the values from x_boxes_1[0] and y_boxes_1[0] and x_boxes_1[1] and y_boxes_1[1] and produce a new list with the coefficients from each individual calculation.
How would I accomplish this?
As far as I understand x_boxes_1 holds the coordinates, and y_boxes_1 holds the points that you want to fit a polynomial. And, you want to call polyfit two times for each corresponding pair. If that is the case, this should work:
import numpy as np
import matplotlib.pyplot as plt
x_boxes_1 = [[1,2,3,4,5,6,7,8],[9,10,11,12,13,14,15,16]]
y_boxes_1 = [[3,5,2,3,1,2,3,4],[2,3,4,1,5,6,7,10]]
zipped = zip(x_boxes_1, y_boxes_1)
z_boxes_1 = [np.polyfit(x,y,6) for x,y in zipped]
Note that degree of the fitting polynomial is 6.
You can plot to verify:
xp_boxes_1 = [np.linspace(1, 8, 100), np.linspace(9, 16, 100)]
for i in [0,1]:
x = x_boxes_1[i]
y = y_boxes_1[i]
z = z_boxex_1[i]
xp = xp_boxes_1[i]
p = np.poly1d(z)
plt.subplot(1,2,i+1)
plt.plot(x, y, '.', xp, p(xp), '-');
I am a little confused by the documentation for scipy.interpolate.RegularGridInterpolator.
Say for instance I have a function f: R^3 => R which is sampled on the vertices of the unit cube. I would like to interpolate so as to find values inside the cube.
import numpy as np
# Grid points / sample locations
X = np.array([[0,0,0], [0,0,1], [0,1,0], [0,1,1], [1,0,0], [1,0,1], [1,1,0], [1,1,1.]])
# Function values at the grid points
F = np.random.rand(8)
Now, RegularGridInterpolator takes a points argument, and a values argument.
points : tuple of ndarray of float, with shapes (m1, ), ..., (mn, )
The points defining the regular grid in n dimensions.
values : array_like, shape (m1, ..., mn, ...)
The data on the regular grid in n dimensions.
I interpret this as being able to call as such:
import scipy.interpolate as irp
rgi = irp.RegularGridInterpolator(X, F)
However, when I do so, I get the following error:
ValueError: There are 8 point arrays, but values has 1 dimensions
What am I misinterpreting in the docs?
Ok I feel silly when I answer my own question, but I found my mistake with help from the documentation of the original regulargrid lib:
https://github.com/JohannesBuchner/regulargrid
points should be a list of arrays that specifies how the points are spaced along each axis.
For example, to take the unit cube as above, I should set:
pts = ( np.array([0,1.]), )*3
or if I had data which was sampled at higher resolution along the last axis, I might set:
pts = ( np.array([0,1.]), np.array([0,1.]), np.array([0,0.5,1.]) )
Finally, values has to be of shape corresponding to the grid laid out implicitly by points. For example,
val_size = map(lambda q: q.shape[0], pts)
vals = np.zeros( val_size )
# make an arbitrary function to test:
func = lambda pt: (pt**2).sum()
# collect func's values at grid pts
for i in range(pts[0].shape[0]):
for j in range(pts[1].shape[0]):
for k in range(pts[2].shape[0]):
vals[i,j,k] = func(np.array([pts[0][i], pts[1][j], pts[2][k]]))
So finally,
rgi = irp.RegularGridInterpolator(points=pts, values=vals)
runs and performs as desired.
Your answer is nicer, and it's perfectly OK for you to accept it. I'm just adding this as an "alternate" way to script it.
import numpy as np
import scipy.interpolate as spint
RGI = spint.RegularGridInterpolator
x = np.linspace(0, 1, 3) # or 0.5*np.arange(3.) works too
# populate the 3D array of values (re-using x because lazy)
X, Y, Z = np.meshgrid(x, x, x, indexing='ij')
vals = np.sin(X) + np.cos(Y) + np.tan(Z)
# make the interpolator, (list of 1D axes, values at all points)
rgi = RGI(points=[x, x, x], values=vals) # can also be [x]*3 or (x,)*3
tst = (0.47, 0.49, 0.53)
print rgi(tst)
print np.sin(tst[0]) + np.cos(tst[1]) + np.tan(tst[2])
returns:
1.93765972087
1.92113615659