Master 3D surface plots, scatter plots, heatmaps, contour plots, and animations. Learn to visualize multi-dimensional data effectively using Matplotlib's 3D capabilities and advanced plotting techniques.
Visualizing multi-dimensional data requires advanced plotting techniques beyond traditional 2D charts. 3D visualizations, heatmaps, contour plots, and animations enable data scientists to explore complex relationships, identify patterns, and communicate insights that would be hidden in two-dimensional representations.
Professional data scientists use these advanced techniques to analyze scientific data, visualize machine learning model performance, explore geographic information, and create engaging presentations. Understanding how to effectively use 3D plots while avoiding common pitfalls (like perceptual distortion) is essential for modern data visualization.
In this lesson, you'll master Matplotlib's mplot3d toolkit for creating interactive 3D visualizations, learn to build professional heatmaps and correlation matrices, implement contour plots for topographic data, and create compelling animations that show data evolution over time.
Matplotlib's mplot3d toolkit provides powerful 3D visualization capabilities. Understanding when and how to use 3D plots effectively is crucial for multi-dimensional data analysis.
When to Use 3D Plots:
When to Avoid 3D Plots:
3D Scatter Plot:
1import matplotlib.pyplot as plt
2import numpy as np
3from mpl_toolkits.mplot3d import Axes3D
4
5# Create figure with 3D projection
6fig = plt.figure(figsize=(12, 5))
7
8# 3D Scatter Plot
9ax1 = fig.add_subplot(121, projection='3d')
10
11# Generate data
12n = 200
13x = np.random.randn(n)
14y = np.random.randn(n)
15z = x**2 + y**2 + np.random.randn(n) * 0.1
16colors = z
17
18# Create 3D scatter
19scatter = ax1.scatter(x, y, z, c=colors, cmap='viridis',
20 s=50, alpha=0.6, edgecolors='black', linewidth=0.5)
21
22# Customize
23ax1.set_xlabel('X Axis', fontsize=11, fontweight='bold', labelpad=10)
24ax1.set_ylabel('Y Axis', fontsize=11, fontweight='bold', labelpad=10)
25ax1.set_zlabel('Z Axis', fontsize=11, fontweight='bold', labelpad=10)
26ax1.set_title('3D Scatter Plot', fontsize=14, fontweight='bold', pad=20)
27
28# Add colorbar
29fig.colorbar(scatter, ax=ax1, shrink=0.5, aspect=5)
30
31# Set viewing angle
32ax1.view_init(elev=20, azim=45)
33
34plt.show()3D Surface Plot:
1import matplotlib.pyplot as plt
2import numpy as np
3from mpl_toolkits.mplot3d import Axes3D
4
5fig = plt.figure(figsize=(12, 10))
6
7# Create meshgrid
8x = np.linspace(-5, 5, 100)
9y = np.linspace(-5, 5, 100)
10X, Y = np.meshgrid(x, y)
11
12# Calculate Z values - various mathematical surfaces
13# Saddle surface
14Z1 = X**2 - Y**2
15
16# Gaussian surface
17Z2 = np.exp(-(X**2 + Y**2) / 10)
18
19# Ripple effect
20Z3 = np.sin(np.sqrt(X**2 + Y**2))
21
22# Plot 1: Surface with solid colors
23ax1 = fig.add_subplot(221, projection='3d')
24surf1 = ax1.plot_surface(X, Y, Z1, cmap='coolwarm',
25 linewidth=0, antialiased=True, alpha=0.8)
26ax1.set_title('Saddle Surface', fontweight='bold')
27ax1.set_xlabel('X')
28ax1.set_ylabel('Y')
29ax1.set_zlabel('Z')
30fig.colorbar(surf1, ax=ax1, shrink=0.5, aspect=5)
31
32# Plot 2: Wireframe
33ax2 = fig.add_subplot(222, projection='3d')
34wire = ax2.plot_wireframe(X, Y, Z2, color='#2563eb',
35 linewidth=0.8, alpha=0.6)
36ax2.set_title('Gaussian Wireframe', fontweight='bold')
37ax2.set_xlabel('X')
38ax2.set_ylabel('Y')
39ax2.set_zlabel('Z')
40
41# Plot 3: Contour3D
42ax3 = fig.add_subplot(223, projection='3d')
43contour = ax3.contour3D(X, Y, Z3, 50, cmap='viridis')
44ax3.set_title('3D Contour Plot', fontweight='bold')
45ax3.set_xlabel('X')
46ax3.set_ylabel('Y')
47ax3.set_zlabel('Z')
48
49# Plot 4: Surface with custom shading
50ax4 = fig.add_subplot(224, projection='3d')
51surf4 = ax4.plot_surface(X, Y, Z3, cmap='plasma',
52 rstride=1, cstride=1, linewidth=0.3,
53 edgecolors='black', alpha=0.9)
54ax4.set_title('Ripple Surface', fontweight='bold')
55ax4.set_xlabel('X')
56ax4.set_ylabel('Y')
57ax4.set_zlabel('Z')
58fig.colorbar(surf4, ax=ax4, shrink=0.5, aspect=5)
59
60plt.tight_layout()
61plt.show()Interactive 3D Rotation:
3D plots in Matplotlib are interactive by default - click and drag to rotate!
Best Practices:
Heatmaps are powerful tools for visualizing 2D data, correlation matrices, and patterns in large datasets. They're essential for exploratory data analysis and feature engineering in machine learning.
What are Heatmaps?
Heatmaps use color intensity to represent numerical values in a matrix format. They're ideal for:
Basic Heatmap:
1import matplotlib.pyplot as plt
2import numpy as np
3
4# Create sample data
5data = np.random.randn(10, 12)
6
7fig, ax = plt.subplots(figsize=(10, 6))
8
9# Create heatmap
10im = ax.imshow(data, cmap='RdYlBu_r', aspect='auto')
11
12# Set ticks and labels
13ax.set_xticks(np.arange(12))
14ax.set_yticks(np.arange(10))
15ax.set_xticklabels([f'Col {i+1}' for i in range(12)])
16ax.set_yticklabels([f'Row {i+1}' for i in range(10)])
17
18# Rotate x labels
19plt.setp(ax.get_xticklabels(), rotation=45, ha='right',
20 rotation_mode='anchor')
21
22# Add colorbar
23cbar = plt.colorbar(im, ax=ax)
24cbar.set_label('Value', rotation=270, labelpad=20)
25
26# Add values as text annotations
27for i in range(10):
28 for j in range(12):
29 text = ax.text(j, i, f'{data[i, j]:.1f}',
30 ha='center', va='center',
31 color='white' if abs(data[i, j]) > 1 else 'black',
32 fontsize=8)
33
34ax.set_title('Heatmap with Annotations', fontsize=14, fontweight='bold')
35plt.tight_layout()
36plt.show()Correlation Matrix Heatmap:
1import matplotlib.pyplot as plt
2import numpy as np
3import pandas as pd
4
5# Create sample dataset
6np.random.seed(42)
7n_samples = 100
8data = {
9 'Feature_A': np.random.randn(n_samples),
10 'Feature_B': np.random.randn(n_samples),
11 'Feature_C': np.random.randn(n_samples),
12 'Feature_D': np.random.randn(n_samples),
13 'Feature_E': np.random.randn(n_samples)
14}
15
16# Add correlations
17data['Feature_B'] = data['Feature_A'] * 0.8 + np.random.randn(n_samples) * 0.4
18data['Feature_D'] = data['Feature_C'] * 0.6 + np.random.randn(n_samples) * 0.5
19
20df = pd.DataFrame(data)
21
22# Calculate correlation matrix
23corr_matrix = df.corr()
24
25# Create figure
26fig, ax = plt.subplots(figsize=(10, 8))
27
28# Create heatmap
29im = ax.imshow(corr_matrix, cmap='coolwarm', aspect='auto',
30 vmin=-1, vmax=1)
31
32# Set ticks
33features = list(corr_matrix.columns)
34ax.set_xticks(np.arange(len(features)))
35ax.set_yticks(np.arange(len(features)))
36ax.set_xticklabels(features)
37ax.set_yticklabels(features)
38
39# Rotate labels
40plt.setp(ax.get_xticklabels(), rotation=45, ha='right')
41
42# Add correlation values
43for i in range(len(features)):
44 for j in range(len(features)):
45 text = ax.text(j, i, f'{corr_matrix.iloc[i, j]:.2f}',
46 ha='center', va='center',
47 color='white' if abs(corr_matrix.iloc[i, j]) > 0.5 else 'black',
48 fontsize=11, fontweight='bold')
49
50# Colorbar
51cbar = plt.colorbar(im, ax=ax)
52cbar.set_label('Correlation Coefficient', rotation=270, labelpad=20, fontsize=11)
53
54# Title
55ax.set_title('Feature Correlation Matrix',
56 fontsize=14, fontweight='bold', pad=20)
57
58plt.tight_layout()
59plt.show()Advanced Heatmap with Hierarchical Clustering:
1import matplotlib.pyplot as plt
2import numpy as np
3from scipy.cluster.hierarchy import dendrogram, linkage
4from scipy.spatial.distance import squareform
5
6# Create correlated data
7np.random.seed(42)
8data = np.random.randn(20, 50)
9
10# Calculate correlation
11corr = np.corrcoef(data)
12
13# Hierarchical clustering
14linkage_matrix = linkage(squareform(1 - corr), method='average')
15
16# Create figure with subplots
17fig = plt.figure(figsize=(12, 10))
18
19# Dendrogram
20ax1 = fig.add_subplot(221)
21dendro = dendrogram(linkage_matrix, ax=ax1, color_threshold=0)
22ax1.set_title('Hierarchical Clustering', fontweight='bold')
23ax1.set_xlabel('Sample Index')
24ax1.set_ylabel('Distance')
25
26# Clustered heatmap
27ax2 = fig.add_subplot(222)
28idx = dendro['leaves']
29im = ax2.imshow(corr[idx, :][:, idx], cmap='RdBu_r', aspect='auto')
30ax2.set_title('Clustered Correlation Matrix', fontweight='bold')
31plt.colorbar(im, ax=ax2)
32
33plt.tight_layout()
34plt.show()Best Practices:
Contour plots show lines of constant value, similar to topographic maps. They're excellent for visualizing functions of two variables and understanding gradient directions.
What are Contour Plots?
Contour plots display 3D data in 2D by connecting points of equal value. They're used for:
Basic Contour Plot:
1import matplotlib.pyplot as plt
2import numpy as np
3
4# Create meshgrid
5x = np.linspace(-3, 3, 100)
6y = np.linspace(-3, 3, 100)
7X, Y = np.meshgrid(x, y)
8
9# Calculate function
10Z = np.sqrt(X**2 + Y**2)
11
12fig, axes = plt.subplots(1, 2, figsize=(14, 5))
13
14# Contour plot
15contour = axes[0].contour(X, Y, Z, levels=10, cmap='viridis')
16axes[0].clabel(contour, inline=True, fontsize=8)
17axes[0].set_title('Contour Plot', fontsize=14, fontweight='bold')
18axes[0].set_xlabel('X', fontweight='bold')
19axes[0].set_ylabel('Y', fontweight='bold')
20axes[0].grid(True, alpha=0.3)
21
22# Filled contour plot
23contourf = axes[1].contourf(X, Y, Z, levels=20, cmap='viridis')
24axes[1].set_title('Filled Contour Plot', fontsize=14, fontweight='bold')
25axes[1].set_xlabel('X', fontweight='bold')
26axes[1].set_ylabel('Y', fontweight='bold')
27plt.colorbar(contourf, ax=axes[1], label='Distance from Origin')
28
29plt.tight_layout()
30plt.show()Advanced Multi-Function Contour:
1import matplotlib.pyplot as plt
2import numpy as np
3
4fig, axes = plt.subplots(2, 2, figsize=(14, 12))
5
6x = np.linspace(-3, 3, 200)
7y = np.linspace(-3, 3, 200)
8X, Y = np.meshgrid(x, y)
9
10# Function 1: Gaussian
11Z1 = np.exp(-(X**2 + Y**2) / 2)
12cf1 = axes[0, 0].contourf(X, Y, Z1, levels=15, cmap='Blues')
13c1 = axes[0, 0].contour(X, Y, Z1, levels=5, colors='black', linewidths=0.5)
14axes[0, 0].clabel(c1, inline=True, fontsize=8)
15axes[0, 0].set_title('Gaussian Distribution', fontweight='bold')
16plt.colorbar(cf1, ax=axes[0, 0])
17
18# Function 2: Saddle
19Z2 = X**2 - Y**2
20cf2 = axes[0, 1].contourf(X, Y, Z2, levels=20, cmap='RdBu_r')
21c2 = axes[0, 1].contour(X, Y, Z2, levels=10, colors='black', linewidths=0.5)
22axes[0, 1].clabel(c2, inline=True, fontsize=8)
23axes[0, 1].set_title('Saddle Function', fontweight='bold')
24plt.colorbar(cf2, ax=axes[0, 1])
25
26# Function 3: Ripple
27Z3 = np.sin(np.sqrt(X**2 + Y**2))
28cf3 = axes[1, 0].contourf(X, Y, Z3, levels=15, cmap='plasma')
29c3 = axes[1, 0].contour(X, Y, Z3, levels=8, colors='white', linewidths=0.8)
30axes[1, 0].clabel(c3, inline=True, fontsize=8, colors='white')
31axes[1, 0].set_title('Ripple Pattern', fontweight='bold')
32plt.colorbar(cf3, ax=axes[1, 0])
33
34# Function 4: Peaks (MATLAB-style)
35Z4 = 3 * (1 - X)**2 * np.exp(-(X**2) - (Y + 1)**2) \
36 - 10 * (X/5 - X**3 - Y**5) * np.exp(-X**2 - Y**2) \
37 - 1/3 * np.exp(-(X + 1)**2 - Y**2)
38cf4 = axes[1, 1].contourf(X, Y, Z4, levels=20, cmap='terrain')
39c4 = axes[1, 1].contour(X, Y, Z4, levels=10, colors='black',
40 linewidths=0.5, alpha=0.6)
41axes[1, 1].clabel(c4, inline=True, fontsize=8)
42axes[1, 1].set_title('Peaks Function', fontweight='bold')
43plt.colorbar(cf4, ax=axes[1, 1])
44
45plt.tight_layout()
46plt.show()Gradient Visualization:
1import matplotlib.pyplot as plt
2import numpy as np
3
4fig, ax = plt.subplots(figsize=(10, 8))
5
6# Create function
7x = np.linspace(-2, 2, 20)
8y = np.linspace(-2, 2, 20)
9X, Y = np.meshgrid(x, y)
10Z = X**2 + Y**2
11
12# Filled contour background
13cf = ax.contourf(X, Y, Z, levels=15, cmap='viridis', alpha=0.6)
14
15# Contour lines
16c = ax.contour(X, Y, Z, levels=10, colors='black', linewidths=1)
17ax.clabel(c, inline=True, fontsize=9)
18
19# Gradient vectors
20dx, dy = np.gradient(Z)
21skip = 2 # Plot every 2nd arrow
22ax.quiver(X[::skip, ::skip], Y[::skip, ::skip],
23 dx[::skip, ::skip], dy[::skip, ::skip],
24 color='red', alpha=0.8, width=0.003)
25
26ax.set_title('Gradient Field with Contours', fontsize=14, fontweight='bold')
27ax.set_xlabel('X', fontweight='bold')
28ax.set_ylabel('Y', fontweight='bold')
29plt.colorbar(cf, ax=ax, label='Function Value')
30
31plt.tight_layout()
32plt.show()Best Practices:
Animations bring data to life by showing temporal evolution, algorithmic processes, or parameter sweeps. Matplotlib's FuncAnimation creates smooth, publication-quality animations.
When to Use Animations:
Basic Animation Structure:
1import matplotlib.pyplot as plt
2import numpy as np
3from matplotlib.animation import FuncAnimation
4
5# Create figure and axis
6fig, ax = plt.subplots(figsize=(10, 6))
7
8# Initialize plot
9line, = ax.plot([], [], lw=2, color='#2563eb')
10ax.set_xlim(0, 2*np.pi)
11ax.set_ylim(-1.5, 1.5)
12ax.grid(True, alpha=0.3)
13ax.set_xlabel('X', fontweight='bold')
14ax.set_ylabel('Y', fontweight='bold')
15ax.set_title('Animated Sine Wave', fontsize=14, fontweight='bold')
16
17# Data
18xdata = np.linspace(0, 2*np.pi, 100)
19
20# Initialization function
21def init():
22 line.set_data([], [])
23 return line,
24
25# Animation function
26def animate(frame):
27 ydata = np.sin(xdata + frame * 0.1)
28 line.set_data(xdata, ydata)
29 return line,
30
31# Create animation
32anim = FuncAnimation(fig, animate, init_func=init,
33 frames=200, interval=20, blit=True)
34
35plt.show()
36
37# Save animation (optional)
38# anim.save('sine_wave.gif', writer='pillow', fps=30)Growing Line Animation:
1import matplotlib.pyplot as plt
2import numpy as np
3from matplotlib.animation import FuncAnimation
4
5fig, ax = plt.subplots(figsize=(10, 6))
6
7x = np.linspace(0, 10, 1000)
8y = np.sin(x) * np.exp(-x/10)
9
10line, = ax.plot([], [], lw=2.5, color='#2563eb')
11ax.set_xlim(0, 10)
12ax.set_ylim(-0.5, 1.2)
13ax.grid(True, alpha=0.3)
14ax.set_title('Growing Line Animation', fontsize=14, fontweight='bold')
15
16def init():
17 line.set_data([], [])
18 return line,
19
20def animate(frame):
21 # Grow line from 0 to full length
22 idx = int(len(x) * frame / 200)
23 line.set_data(x[:idx], y[:idx])
24 return line,
25
26anim = FuncAnimation(fig, animate, init_func=init,
27 frames=200, interval=20, blit=True)
28
29plt.show()Multiple Objects Animation:
1import matplotlib.pyplot as plt
2import numpy as np
3from matplotlib.animation import FuncAnimation
4
5fig, ax = plt.subplots(figsize=(10, 8))
6
7# Setup
8n_particles = 50
9positions = np.random.rand(n_particles, 2) * 10
10velocities = (np.random.rand(n_particles, 2) - 0.5) * 0.2
11
12scatter = ax.scatter(positions[:, 0], positions[:, 1],
13 s=100, c=range(n_particles), cmap='viridis',
14 alpha=0.8, edgecolors='black', linewidth=1)
15
16ax.set_xlim(0, 10)
17ax.set_ylim(0, 10)
18ax.set_title('Particle Motion Animation', fontsize=14, fontweight='bold')
19ax.grid(True, alpha=0.3)
20
21def init():
22 scatter.set_offsets(positions)
23 return scatter,
24
25def animate(frame):
26 global positions, velocities
27
28 # Update positions
29 positions += velocities
30
31 # Bounce off walls
32 for i in range(n_particles):
33 if positions[i, 0] < 0 or positions[i, 0] > 10:
34 velocities[i, 0] *= -1
35 if positions[i, 1] < 0 or positions[i, 1] > 10:
36 velocities[i, 1] *= -1
37
38 scatter.set_offsets(positions)
39 return scatter,
40
41anim = FuncAnimation(fig, animate, init_func=init,
42 frames=300, interval=30, blit=True)
43
44plt.show()3D Surface Animation:
1import matplotlib.pyplot as plt
2import numpy as np
3from matplotlib.animation import FuncAnimation
4from mpl_toolkits.mplot3d import Axes3D
5
6fig = plt.figure(figsize=(10, 8))
7ax = fig.add_subplot(111, projection='3d')
8
9# Create meshgrid
10x = np.linspace(-3, 3, 100)
11y = np.linspace(-3, 3, 100)
12X, Y = np.meshgrid(x, y)
13
14def init():
15 ax.clear()
16 return []
17
18def animate(frame):
19 ax.clear()
20
21 # Animated surface
22 Z = np.sin(np.sqrt(X**2 + Y**2) + frame * 0.1)
23
24 surf = ax.plot_surface(X, Y, Z, cmap='viridis',
25 linewidth=0, antialiased=True, alpha=0.9)
26
27 ax.set_zlim(-1, 1)
28 ax.set_xlabel('X')
29 ax.set_ylabel('Y')
30 ax.set_zlabel('Z')
31 ax.set_title(f'Animated 3D Surface - Frame {frame}',
32 fontweight='bold')
33
34 return [surf]
35
36anim = FuncAnimation(fig, animate, init_func=init,
37 frames=100, interval=50, blit=False)
38
39plt.show()Best Practices:
Complex 3D plots and animations can be computationally expensive. Understanding optimization techniques ensures smooth, responsive visualizations.
Performance Bottlenecks:
Optimization Techniques:
1. Downsampling:
1import matplotlib.pyplot as plt
2import numpy as np
3
4# Original data: 1 million points
5n_original = 1000000
6x_original = np.random.randn(n_original)
7y_original = np.random.randn(n_original)
8
9# Downsample to 10,000 points
10n_downsample = 10000
11idx = np.random.choice(n_original, n_downsample, replace=False)
12x = x_original[idx]
13y = y_original[idx]
14
15# Plot downsampled data
16fig, ax = plt.subplots(figsize=(10, 6))
17ax.scatter(x, y, alpha=0.5, s=20)
18ax.set_title(f'Downsampled: {n_downsample:,} of {n_original:,} points',
19 fontweight='bold')
20plt.show()2. Reduce Surface Resolution:
1import matplotlib.pyplot as plt
2import numpy as np
3from mpl_toolkits.mplot3d import Axes3D
4
5fig = plt.figure(figsize=(14, 5))
6
7# High resolution (slow)
8ax1 = fig.add_subplot(121, projection='3d')
9x_high = np.linspace(-3, 3, 200) # 200 points
10y_high = np.linspace(-3, 3, 200)
11X_high, Y_high = np.meshgrid(x_high, y_high)
12Z_high = np.sin(np.sqrt(X_high**2 + Y_high**2))
13
14surf1 = ax1.plot_surface(X_high, Y_high, Z_high, cmap='viridis')
15ax1.set_title('High Resolution (40,000 points)', fontweight='bold')
16
17# Lower resolution (fast)
18ax2 = fig.add_subplot(122, projection='3d')
19x_low = np.linspace(-3, 3, 50) # 50 points
20y_low = np.linspace(-3, 3, 50)
21X_low, Y_low = np.meshgrid(x_low, y_low)
22Z_low = np.sin(np.sqrt(X_low**2 + Y_low**2))
23
24surf2 = ax2.plot_surface(X_low, Y_low, Z_low, cmap='viridis')
25ax2.set_title('Lower Resolution (2,500 points)', fontweight='bold')
26
27plt.tight_layout()
28plt.show()3. Use Blitting for Animations:
1# Bad: blit=False (redraws entire figure)
2anim = FuncAnimation(fig, animate, frames=100,
3 interval=20, blit=False)
4
5# Good: blit=True (only redraws changed artists)
6anim = FuncAnimation(fig, animate, frames=100,
7 interval=20, blit=True)4. Limit Update Frequency:
1# Update every Nth frame instead of every frame
2def animate(frame):
3 if frame % 5 == 0: # Update every 5th frame
4 # Update plot
5 pass
6 return artists,5. Use Efficient Data Structures:
1# Slow: Python lists
2data = [[1, 2], [3, 4], [5, 6]]
3
4# Fast: NumPy arrays
5data = np.array([[1, 2], [3, 4], [5, 6]])Best Practices:
Comprehensive demonstration of 3D plots, heatmaps, contour plots, and animations using advanced Matplotlib techniques.
1import matplotlib.pyplot as plt
2import numpy as np
3from mpl_toolkits.mplot3d import Axes3D
4from matplotlib.animation import FuncAnimation
5import matplotlib.gridspec as gridspec
6
7print("3D Visualizations and Advanced Plots Showcase")
8print("=" * 60)
9
10# ==========================================
11# 1. 3D SURFACE AND SCATTER PLOTS
12# ==========================================
13print("
141. 3D Surface and Scatter Plots")
15print("-" * 60)
16
17fig = plt.figure(figsize=(14, 10))
18gs = gridspec.GridSpec(2, 2, figure=fig, hspace=0.3, wspace=0.3)
19
20# 3D Scatter Plot
21ax1 = fig.add_subplot(gs[0, 0], projection='3d')
22
23n = 300
24x = np.random.randn(n)
25y = np.random.randn(n)
26z = x**2 + y**2 + np.random.randn(n) * 0.5
27colors = z
28
29scatter = ax1.scatter(x, y, z, c=colors, cmap='plasma',
30 s=30, alpha=0.6, edgecolors='black', linewidth=0.5)
31
32ax1.set_xlabel('X', fontweight='bold', labelpad=10)
33ax1.set_ylabel('Y', fontweight='bold', labelpad=10)
34ax1.set_zlabel('Z', fontweight='bold', labelpad=10)
35ax1.set_title('3D Scatter: Paraboloid with Noise', fontweight='bold')
36ax1.view_init(elev=25, azim=45)
37fig.colorbar(scatter, ax=ax1, shrink=0.5, aspect=5)
38
39# 3D Surface Plot
40ax2 = fig.add_subplot(gs[0, 1], projection='3d')
41
42x_surf = np.linspace(-3, 3, 80)
43y_surf = np.linspace(-3, 3, 80)
44X, Y = np.meshgrid(x_surf, y_surf)
45Z = np.exp(-(X**2 + Y**2) / 4) * np.sin(X) * np.cos(Y)
46
47surf = ax2.plot_surface(X, Y, Z, cmap='viridis',
48 linewidth=0, antialiased=True, alpha=0.9)
49
50ax2.set_xlabel('X', fontweight='bold')
51ax2.set_ylabel('Y', fontweight='bold')
52ax2.set_zlabel('Z', fontweight='bold')
53ax2.set_title('3D Surface: Complex Function', fontweight='bold')
54ax2.view_init(elev=30, azim=120)
55fig.colorbar(surf, ax=ax2, shrink=0.5, aspect=5)
56
57print("Created 3D scatter and surface plots")
58print(f" - Scatter: {n} points")
59print(f" - Surface: {80*80} grid points")
60
61# ==========================================
62# 2. HEATMAP AND CORRELATION MATRIX
63# ==========================================
64print("
652. Heatmap and Correlation Matrix")
66print("-" * 60)
67
68# Generate correlated data
69np.random.seed(42)
70n_features = 8
71feature_names = [f'Feature_{i+1}' for i in range(n_features)]
72
73# Create correlation matrix with some structure
74base_corr = np.eye(n_features)
75for i in range(n_features):
76 for j in range(i+1, n_features):
77 if abs(i - j) == 1: # Adjacent features
78 base_corr[i, j] = base_corr[j, i] = 0.7 + np.random.rand() * 0.2
79 elif abs(i - j) == 2: # One apart
80 base_corr[i, j] = base_corr[j, i] = 0.3 + np.random.rand() * 0.3
81 else:
82 base_corr[i, j] = base_corr[j, i] = -0.2 + np.random.rand() * 0.4
83
84ax3 = fig.add_subplot(gs[1, 0])
85
86im = ax3.imshow(base_corr, cmap='RdBu_r', aspect='auto',
87 vmin=-1, vmax=1)
88
89ax3.set_xticks(np.arange(n_features))
90ax3.set_yticks(np.arange(n_features))
91ax3.set_xticklabels(feature_names, rotation=45, ha='right')
92ax3.set_yticklabels(feature_names)
93
94# Add correlation values
95for i in range(n_features):
96 for j in range(n_features):
97 color = 'white' if abs(base_corr[i, j]) > 0.5 else 'black'
98 text = ax3.text(j, i, f'{base_corr[i, j]:.2f}',
99 ha='center', va='center',
100 color=color, fontsize=9, fontweight='bold')
101
102ax3.set_title('Feature Correlation Matrix', fontweight='bold')
103cbar = fig.colorbar(im, ax=ax3)
104cbar.set_label('Correlation', rotation=270, labelpad=15)
105
106print(f"Created {n_features}x{n_features} correlation matrix")
107
108# ==========================================
109# 3. CONTOUR PLOTS
110# ==========================================
111print("
1123. Contour and Filled Contour Plots")
113print("-" * 60)
114
115ax4 = fig.add_subplot(gs[1, 1])
116
117# Create peaks function
118x_cont = np.linspace(-3, 3, 150)
119y_cont = np.linspace(-3, 3, 150)
120X_cont, Y_cont = np.meshgrid(x_cont, y_cont)
121
122Z_cont = 3 * (1 - X_cont)**2 * np.exp(-(X_cont**2) - (Y_cont + 1)**2) \
123 - 10 * (X_cont/5 - X_cont**3 - Y_cont**5) * np.exp(-X_cont**2 - Y_cont**2) \
124 - 1/3 * np.exp(-(X_cont + 1)**2 - Y_cont**2)
125
126# Filled contour
127cf = ax4.contourf(X_cont, Y_cont, Z_cont, levels=20, cmap='terrain')
128
129# Contour lines
130c = ax4.contour(X_cont, Y_cont, Z_cont, levels=10,
131 colors='black', linewidths=0.8, alpha=0.4)
132ax4.clabel(c, inline=True, fontsize=8, fmt='%.1f')
133
134ax4.set_xlabel('X', fontweight='bold')
135ax4.set_ylabel('Y', fontweight='bold')
136ax4.set_title('Filled Contour: Peaks Function', fontweight='bold')
137cbar2 = fig.colorbar(cf, ax=ax4)
138cbar2.set_label('Height', rotation=270, labelpad=15)
139
140print("Created contour plot with 20 filled levels and 10 contour lines")
141
142plt.suptitle('Advanced 3D and Multi-Dimensional Visualizations',
143 fontsize=16, fontweight='bold', y=0.995)
144
145plt.show()
146
147# ==========================================
148# 4. ANIMATION DEMONSTRATION
149# ==========================================
150print("
1514. Animation with FuncAnimation")
152print("-" * 60)
153
154fig_anim, axes_anim = plt.subplots(1, 2, figsize=(14, 5))
155
156# Animation 1: Growing sine wave
157line1, = axes_anim[0].plot([], [], lw=2.5, color='#2563eb')
158axes_anim[0].set_xlim(0, 4*np.pi)
159axes_anim[0].set_ylim(-1.5, 1.5)
160axes_anim[0].grid(True, alpha=0.3)
161axes_anim[0].set_xlabel('X (radians)', fontweight='bold')
162axes_anim[0].set_ylabel('Y', fontweight='bold')
163axes_anim[0].set_title('Growing Sine Wave', fontsize=12, fontweight='bold')
164
165x_anim = np.linspace(0, 4*np.pi, 200)
166y_anim = np.sin(x_anim)
167
168# Animation 2: Bouncing particles
169n_particles = 30
170particle_pos = np.random.rand(n_particles, 2) * 10
171particle_vel = (np.random.rand(n_particles, 2) - 0.5) * 0.3
172
173scatter_anim = axes_anim[1].scatter(particle_pos[:, 0], particle_pos[:, 1],
174 s=100, c=range(n_particles),
175 cmap='viridis', alpha=0.8,
176 edgecolors='black', linewidth=1)
177
178axes_anim[1].set_xlim(0, 10)
179axes_anim[1].set_ylim(0, 10)
180axes_anim[1].grid(True, alpha=0.3)
181axes_anim[1].set_xlabel('X', fontweight='bold')
182axes_anim[1].set_ylabel('Y', fontweight='bold')
183axes_anim[1].set_title('Bouncing Particles', fontsize=12, fontweight='bold')
184
185def init():
186 line1.set_data([], [])
187 scatter_anim.set_offsets(particle_pos)
188 return line1, scatter_anim
189
190def animate(frame):
191 global particle_pos, particle_vel
192
193 # Update growing line
194 idx = int(len(x_anim) * min(frame / 100, 1))
195 line1.set_data(x_anim[:idx], y_anim[:idx])
196
197 # Update particles
198 particle_pos += particle_vel
199
200 # Bounce off walls
201 for i in range(n_particles):
202 if particle_pos[i, 0] < 0 or particle_pos[i, 0] > 10:
203 particle_vel[i, 0] *= -1
204 if particle_pos[i, 1] < 0 or particle_pos[i, 1] > 10:
205 particle_vel[i, 1] *= -1
206
207 scatter_anim.set_offsets(particle_pos)
208
209 return line1, scatter_anim
210
211anim = FuncAnimation(fig_anim, animate, init_func=init,
212 frames=200, interval=30, blit=True)
213
214print("Created dual animation:")
215print(" - Growing sine wave (left)")
216print(f" - {n_particles} bouncing particles (right)")
217print(" - 200 frames at 30ms intervals")
218
219plt.tight_layout()
220plt.show()
221
222# ==========================================
223# FINAL SUMMARY
224# ==========================================
225print("
226" + "=" * 60)
227print("3D VISUALIZATIONS AND ADVANCED PLOTS - SUMMARY")
228print("=" * 60)
229print()
230print("✓ 3D Scatter and Surface Plots")
231print(" - Interactive 3D scatter with color mapping")
232print(" - Smooth surface plots with custom colormaps")
233print(" - Proper viewing angles and axis labels")
234print()
235print("✓ Heatmaps and Correlation Matrices")
236print(" - Color-coded correlation analysis")
237print(" - Value annotations for readability")
238print(" - Diverging colormaps for signed data")
239print()
240print("✓ Contour Plots")
241print(" - Filled contour backgrounds")
242print(" - Labeled contour lines")
243print(" - Topographic visualization")
244print()
245print("✓ Animations")
246print(" - Smooth frame-by-frame updates")
247print(" - Multiple animated objects")
248print(" - Efficient blitting for performance")
249print()
250print("All techniques ready for production use!")
251print("=" * 60)This comprehensive demonstration showcases advanced 3D visualization and multi-dimensional plotting techniques:
🎯 3D Visualizations:
📊 Heatmaps and Correlations:
🗺️ Contour Plots:
🎬 Animations:
⚡ Performance Optimization:
🎨 Professional Styling:
💡 Real-World Applications:
🔧 Technical Highlights:
This showcase demonstrates production-ready techniques for visualizing complex, multi-dimensional data in professional settings.
Excellent work mastering 3D visualizations and advanced plots! You now understand surface plots, heatmaps, contours, and animations. In our next lesson, "Seaborn for Statistical Visualizations," you'll learn to create beautiful statistical plots using Seaborn's high-level API, including distribution plots, categorical visualizations, and regression analysis. Get ready to level up your statistical visualization skills!
Your progress is saved in this browser, on this device only.