how to graph 3 3D plot next to each other in python? - matplotlib

how I can graph 3D graph with the following code next to each other? subplot dosen't work like a 2D plt.plot()
ax = plt.axes(projection='3d')
f0 = plt.figure(figsize=(15,5))
ax.scatter3D(X,Y ,Z,facecolor="yellow")
I want to use this code to print 3 graphs next to each other horizantaly.

This is a starting point:
import numpy as np
import matplotlib.pyplot as plt
x, y = np.mgrid[-2:2:50j, -2:2:50j]
z = np.cos(x**2 + y**2)
fig, axs = plt.subplots(1, 3, subplot_kw={"projection": "3d"}, figsize=(10, 5))
axs[0].plot_surface(x, y, z)
axs[1].plot_wireframe(x, y, z, rstride=3, cstride=3)
axs[2].plot_surface(x, y, z, alpha=0.25)
axs[2].plot_wireframe(x, y, z, rstride=3, cstride=3, color="k", lw=0.5)
plt.show()

Related

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()

Matplotlib 3d barplot failing to draw just one face

import numpy as np
import matplotlib.pyplot as plt
x, y = np.array([[x, y] for x in range(5) for y in range(x+1)]).T
z = 1/ (5*x + 5)
fig = plt.figure()
ax = fig.gca(projection = '3d')
ax.bar3d(x, y, np.zeros_like(z), dx = 1, dy = 1, dz = z)
yields
How do I get the face at (1,0) to display properly?
There is currently no good solution to this. Fortunately though, it happens only for some viewing angles. So you can choose an angle where it plots fine, e.g.
ax.view_init(azim=-60, elev=25)

Errorbar variable marker size

I want to plot some data x and y in which I need the marker size to depend on a third array z. I could plot them separately (i.e., scatter x and y with size = z, and errorbar without marker, fmc = 'none') and this solves it. The problem is that I need the legend to show the errorbar AND the dot, together:
and not
Code is here with some made-up data:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(1,10,100)
y = 2*x
yerr = np.random(0.5,1.0,100)
z = np.random(1,10,100)
fig, ax = plt.subplots()
plt.scatter(x, y, s=z, facecolors='', edgecolors='red', label='Scatter')
ax.errorbar(x, y, yerr=yerr, xerr=0, fmt='none', mfc='o', color='red', capthick=1, label='Error bar')
plt.legend()
plt.show()
which produces the legend I want to avoid:
In errorbar the argumentmarkersizedoes not accept arrays asscatter` does.
The idea is usually to use a proxy to put into the legend. So while the errorbar in the plot may have no marker, the one in the legend has a marker set.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(1,10,11)
y = 2*x
yerr = np.random.rand(11)*5
z = np.random.rand(11)*2+5
fig, ax = plt.subplots()
sc = ax.scatter(x, y, s=z**2, facecolors='', edgecolors='red')
errb = ax.errorbar(x, y, yerr=yerr, xerr=0, fmt='none',
color='red', capthick=1, label="errorbar")
proxy = ax.errorbar([], [], yerr=[], xerr=[], marker='o', mfc="none", mec="red",
color='red', capthick=1, label="errorbar")
ax.legend(handles=[proxy], labels=["errorbar"])
plt.show()

pyplot: loglog contour with labels fix angle

This is an extension of a related question.
I intend to make a contour plot, with labeled contours, then change the axes scales to 'log'.
This works fine except that the rotation of the contour labels is not adjusted. Can this be fixed?
loglog = False
import matplotlib.pyplot as plt
import numpy as np
x = (np.linspace(0, 10))
y = (np.linspace(0, 10))
X, Y = np.meshgrid(x, y)
C = plt.contour(X, Y, np.sqrt(X) * Y)
plt.clabel(C, inline=1, fontsize=10)
plt.xlim(1, 10)
plt.ylim(1, 10)
if loglog: plt.xscale('log')
if loglog: plt.yscale('log')
plt.show()
The fist plot is obtained with loglog=False in the second loglog=True:
So the answer is actually obvious. Changing the the axes scale types in advance helps, of course.
Edit:
I think it makes sense to use logspace instead of linspace here.
import matplotlib.pyplot as plt
import numpy as np
x = np.logspace(0, 1, 100, base=10)
y = np.logspace(0, 1, 100, base=10)
X, Y = np.meshgrid(x, y)
plt.xlim(1, 10)
plt.ylim(1, 10)
plt.xscale('log')
plt.yscale('log')
C = plt.contour(X, Y, np.sqrt(X) * Y)
plt.clabel(C, inline=1, fontsize=10)

Python Subplot 3d Surface and Heat Map

I plan to create a figure in matplotlib, with a 3D surface on the left and its corresponding contour map on the right.
I used subplots but it only show the contour map (with blank space for the surface), and a separate figure for the surface.
Is it possible to create these plots in one figure side-by side?
EDIT: The code is as follows:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
import numpy as np
x = np.arange(-5, 5, 0.25)
y = np.arange(-5, 5, 0.25)
x, y = np.meshgrid(x, y)
r = np.sqrt(x**2 + y**2)
z = np.sin(r)
fig, (surf, cmap) = plt.subplots(1, 2)
fig = plt.figure()
surf = fig.gca(projection='3d')
surf.plot_surface(x,y,z)
cmap.contourf(x,y,z,25)
plt.show()
I guess it's hard to use plt.subplots() in order to create a grid of plots with different projections.
So the most straight forward solution is to create each subplot individually with plt.subplot.
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
import numpy as np
x = np.arange(-5, 5, 0.25)
y = np.arange(-5, 5, 0.25)
x, y = np.meshgrid(x, y)
r = np.sqrt(x**2 + y**2)
z = np.sin(r)
ax = plt.subplot(121, projection='3d')
ax.plot_surface(x,y,z)
ax2 = plt.subplot(122)
ax2.contourf(x,y,z,25)
plt.show()
Of course one may also use the gridspec capabilities for more sophisticated grid structures.