The purpose of this repository is to show an example of a way of bringing the Python 3 matplotlib.pyplot.fill_between
function to 3D plots.
The main fill_between_3d
function can be found in the FillBetween3d.py file of this repository.
You can see the images of this README file displayed together at the image gallery.
The needed imports for these three examples will be
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
This example shows how to plot three lines with fill_between_3d
applied to them in three different equidistant layers. The code is the following:
# x axis 1D space.
x = np.linspace(-10,10,100)
# Define the three functions to plot.
f1 = np.sin(0.25*x)**2 * np.exp(-0.1*(x+0.7)**2)
f2 = np.sin( 0.5*x)**2 * np.exp(-0.1*(x+0.7)**2)
f3 = np.sin( x)**2 * np.exp(-0.1*(x+0.7)**2)
# Sets of [x, y, 0] lines (with constant y) for defining the bases of the polygons.
set01 = [x, -7*np.ones(len(x)), np.zeros(len(x))]
set02 = [x, 0*np.ones(len(x)), np.zeros(len(x))]
set03 = [x, 7*np.ones(len(x)), np.zeros(len(x))]
# Sets of the form [x, y, fi] (with constant y) representing each function 3D line.
set1 = [x, -7*np.ones(len(x)), f1]
set2 = [x, 0*np.ones(len(x)), f2]
set3 = [x, 7*np.ones(len(x)), f3]
# Plotting part. Figure and axes creation.
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d', xlim=(-10,10), ylim=(-10,10))
# Plot the f1 line and its fill_between_3d.
ax.plot(*set1, lw=2, zorder=20, c="C0")
fill_between_3d(ax, *set01, *set1, mode = 1, c="C0")
# Plot the f2 line and its fill_between_3d.
ax.plot(*set2, lw=2, zorder=15, c="C1")
fill_between_3d(ax, *set02, *set2, mode = 1, c="C1")
# Plot the f3 line and its fill_between_3d.
ax.plot(*set3, lw=2, zorder=10, c="C2")
fill_between_3d(ax, *set03, *set3, mode = 1, c="C2")
# Correct the z limit of the plot.
ax.set_zlim((0,np.max([f1,f2,f3])))
# Show the plot.
plt.show()
The result is
mode = 1 |
mode = 2 |
---|
This second and simpler example shows how the fill_between_3d
function fills the area between two arbitrary lines laying in the 3d space.
x = np.linspace(-1,1,100)
y = np.linspace(-1,1,100)
set1 = [x, np.cos(2*np.pi*y), np.sin(2*np.pi*y)] # x, y, z coordinates of the first line (x1, y1, z1)
set2 = [x, 2*np.cos(2*np.pi*y), 2*np.sin(2*np.pi*y)] # x, y, z coordinates of the second line (x2, y2, z2)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(*set1, lw=4)
ax.plot(*set2, lw=4)
fill_between_3d(ax, *set1, *set2, mode = 1)
plt.show()
This function can also be used to fill the area between two lines like the matplotlib's fill_between
function does in 2D plots but with 3D lines.
x = np.linspace(-2,2,100)
y = np.linspace(-2,2,100)
set1 = [x, np.zeros(len(x)), np.exp(-(x-0.5)**2)]
set2 = [x, np.zeros(len(x)), 0.5*np.exp(-(x)**2)]
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(*set1, lw=4)
ax.plot(*set2, lw=4)
fill_between_3d(ax, *set1, *set2, mode = 1)
plt.show()
Adding
X, Y = np.meshgrid(x, y)
Z = 0.5*np.exp(-(X**2+Y**2))
ax.plot_surface(X, Y, Z, color='darkorange', alpha=0.8)
to the code of this example results in: