Matplotlib contour map error : Input z must be 2D, not 1D - matplotlib

I am trying to draw contour map using matplotlib.
I used one column of data with Z data.
I can't understand why Z should be 2d.
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
y_test_pred= gb_regressor.predict(X_test)
X_test_conx=X_test.values[:,0]
X_test_cony=X_test.values[:,1]
[X, Y] = np.meshgrid(X_test_conx, X_test_cony)
Z = y_test_pred
fig, ax = plt.subplots(1, 1)
ax.contourf(X, Y, Z)
TypeError: Input z must be 2D, not 1D
How should I modify the Z data??
Please help me....

Related

Vector field with numpy and a curve

I'm trying to create a vector field and some curve, I've created a vector field as shown
import matplotlib.pyplot as plt
import numpy as np
x,y = np.meshgrid(np.arange(-3,3,.35),np.arange(-3,3,.35))
u = x
v = y
plt.quiver(x, y, u, v, color = 'black')
plt.show()
But I want to add the curve $y=x^2$ in the same plot, how could I do that?
I've tryeid to add plt.plot and the curve but the result is weird.
You probably want to keep the y-axis limit as was in the mesh grid. plt.ylim is helpful in that case
import matplotlib.pyplot as plt
import numpy as np
x, y = np.meshgrid(np.arange(-3, 3, .35), np.arange(-3, 3, .35))
u = x
v = y
plt.quiver(x, y, u, v, color = 'black')
x = np.linspace(-3, 3, 100)
ylim = plt.ylim()
plt.plot(x, x**2)
plt.ylim(ylim)
plt.show()
Output:

Setting Axis ticks of an Axes3D object

I'm new to visualizing data with matplotlib. Currently I'm trying to create an Axis3D object where each axis has ticks from 0 to 11, but only the ticks from 1 to 10 are labeled with the actual numbers. My code looks like this:
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
x = [3]
y = [5]
z = [8]
ax.plot(x, y, z, c='r', marker = 'o')
ax.set_xlabel('Förderung der \n lokalen Ökonomie',labelpad=10)
ax.set_ylabel('Kulturelle und \n soziale Integration',labelpad=10)
ax.set_zlabel('Einfluss auf \n natürliche Umwelt',labelpad=10)
ax.set_xticks([0,1,2,3,4,5,6,7,8,9,10,11])
ax.set_yticks([0,1,2,3,4,5,6,7,8,9,10,11])
ax.set_zticks([0,1,2,3,4,5,6,7,8,9,10,11])
x_label = ["",1,2,3,4,5,6,7,8,9,10,""]
y_label= ["",1,2,3,4,5,6,7,8,9,10,""]
z_label= ["",1,2,3,4,5,6,7,8,9,10,""]
plt.title("Hotel X, Pontresina (CH)")
ax.set_xticklabels(x_label )
ax.set_yticklabels(y_label)
ax.set_zticklabels(z_label)
plt.show()
I was able to get the code running for a 2D object but for the 3D object I only get one tick and one tick label per axis. Would be really grateful if you could help me out!
Cheers!

ValueError: Contour levels must be increasing - how to plot 3 feature data

import numpy as np
from matplotlib import pyplot as plt
data = np.random.normal(0,1,[100,3])
x = data[:,0]
y = data[:,1]
z = data[:,2]
plt.contour([x,y],z)
When I run this code with dummy data I get:
ValueError: Contour levels must be increasing
Do you have any idea what would this mean and how I could fix it?
plt.contour is a bit particular about its input, the z values must be on values on a rectangular 2D grid, see for example:
import matplotlib.pyplot as plt
import numpy as np
x = np.expand_dims(np.arange(1,11,1), axis=1)
y = np.expand_dims(np.arange(2,21,2), axis=0)
z = y * x
print(x.shape)
print(y.shape)
print(z.shape)
plt.figure()
plt.contour(z)
plt.show()
You can also provide x and y values for plt.contour by using np.meshgrid :
XX,YY = np.meshgrid(x,y)
plt.figure()
plt.contour(XX, YY, z)
plt.show()
If you have z-values with irregular values for x and y, you might use plt.tricontour, see the following example:
from matplotlib.tri import Triangulation
data = np.random.normal(0,1,[100,3])
x = data[:,0]
y = data[:,1]
#z = data[:,2]
z = x * y
tri = Triangulation(x,y)
plt.figure()
plt.tricontour(tri, z, )
plt.scatter(x,y, c=z)
plt.show()
Edit: from JohanC's comment i learned that this can be simplified without importing matplotlib.tri by:
plt.figure()
plt.tricontour(x,y,z)
plt.scatter(x,y, c=z)
plt.show()

Visualize 1-dimensional data in a sequential colormap

I have a pandas series containing numbers ranging between 0 and 100. I want to visualise it in a horizontal bar consisting of 3 main colours.
I have tried using seaborn but all I can get is a heatmap matrix. I have also tried the below code, which is producing what I need but not in the way I need it.
x = my_column.values
y = x
t = x
fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.scatter(x, y, c=t, cmap='brg')
ax2.scatter(x, y, c=t, cmap='brg')
plt.show()
What I'm looking for is something similar to the below figure, how can I achieve that using matplotlib or seaborn?
The purpose of this is not quite clear, however, the following would produce an image like the one shown in the question:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
x = np.linspace(100,0,101)
fig, ax = plt.subplots(figsize=(6,1), constrained_layout=True)
cmap = LinearSegmentedColormap.from_list("", ["limegreen", "gold", "crimson"])
ax.imshow([x], cmap=cmap, aspect="auto",
extent=[x[0]-np.diff(x)[0]/2, x[-1]+np.diff(x)[0]/2,0,1])
ax.tick_params(axis="y", left=False, labelleft=False)
plt.show()

Combined legend entry for plot and fill_between

This is similar to Matlab: Combine the legends of shaded error and solid line mean, except for Matplotlib. Example code:
import numpy as np
import matplotlib.pyplot as plt
x = np.array([0,1])
y = x + 1
f,a = plt.subplots()
a.fill_between(x,y+0.5,y-0.5,alpha=0.5,color='b')
a.plot(x,y,color='b',label='Stuff',linewidth=3)
a.legend()
plt.show()
The above code produces a legend that looks like this:
How can I create a legend entry that combines the shading from fill_between and the line from plot, so that it looks something like this (mockup made in Gimp):
MPL supports tuple inputs to legend so that you can create composite legend entries (see the last figure on this page). However, as of now PolyCollections--which fill_between creates/returns--are not supported by legend, so simply supplying a PolyCollection as an entry in a tuple to legend won't work (a fix is anticipated for mpl 1.5.x).
Until the fix arrives I would recommend using a proxy artist in conjunction with the 'tuple' legend entry functionality. You could use the mpl.patches.Patch interface (as demonstrated on the proxy artist page) or you could just use fill. e.g.:
import numpy as np
import matplotlib.pyplot as plt
x = np.array([0, 1])
y = x + 1
f, a = plt.subplots()
a.fill_between(x, y + 0.5, y - 0.5, alpha=0.5, color='b')
p1 = a.plot(x, y, color='b', linewidth=3)
p2 = a.fill(np.NaN, np.NaN, 'b', alpha=0.5)
a.legend([(p2[0], p1[0]), ], ['Stuff'])
plt.show()