Advanced Matplotlib: Color Maps, Annotations, Subplots, 3D Plots, Contours, Heatmaps, and Pandas Plot
Basic Matplotlib helps you draw simple charts.
Advanced Matplotlib helps you explain data clearly.
In this guide, you will move from single charts to richer analytical visuals:
- colored scatter plots
- color maps and colorbars
- transparency with
alpha - larger figure sizes
- annotations and text labels
- horizontal and vertical reference lines
- subplots with shared axes
- custom figure layouts with
add_subplot - 3D scatter plots
- 3D line plots
- 3D surface plots
- contour plots
- heatmaps
- Pandas
.plot()shortcuts
The examples use original synthetic datasets, not copied notebook or public course data.
Files Used In This Guide
Use these CSV files:
matplotlib_advanced_energy_plants.csvmatplotlib_advanced_stock_monthly.csv
They are small enough to inspect manually but rich enough for advanced visualization practice.
What You Will Learn
By the end, you should be able to:
- color scatter points by a third variable
- choose and apply Matplotlib color maps
- add a colorbar to explain encoded colors
- use
alphato handle overlapping points - change figure size and resolution
- place text labels on selected points
- annotate specific insights with arrows
- add
axhlineandaxvlinereference lines - create one-row, one-column, and grid subplots
- use
sharexandsharey - use
fig.add_subplot - build 3D scatter, line, and surface plots
- convert 3D surfaces into 2D contour plots
- create heatmaps with
imshow - use Pandas
.plot()for quick visual exploration - solve advanced visualization practice problems
1. Setup
import numpy as np
import pandas as pd
import matplotlib.pyplot as pltLoad the datasets:
plants = pd.read_csv("matplotlib_advanced_energy_plants.csv")
stocks = pd.read_csv("matplotlib_advanced_stock_monthly.csv")
stocks["date"] = pd.to_datetime(stocks["date"])
print(plants.head())
print(stocks.head())The plants table contains energy plant performance metrics.
The stocks table contains monthly close price and volume for five fictional tickers in 2021.
2. Colored Scatter Plots
A basic scatter plot uses two numeric columns.
A colored scatter plot adds a third variable using color.
Example:
- x-axis: monitored capacity
- y-axis: actual energy output
- color: availability percentage
plt.figure(figsize=(8, 5))
plt.scatter(
plants["rated_capacity_mw"],
plants["actual_mu"],
c=plants["availability_pct"],
)
plt.title("Capacity vs Actual Output")
plt.xlabel("Rated Capacity (MW)")
plt.ylabel("Actual Output (MU)")
plt.show()The chart works, but the colors are not explained yet.
3. Color Maps And Colorbars
A color map converts numbers into colors.
plt.figure(figsize=(8, 5))
points = plt.scatter(
plants["rated_capacity_mw"],
plants["actual_mu"],
c=plants["availability_pct"],
cmap="viridis",
)
plt.colorbar(points, label="Availability (%)")
plt.title("Capacity vs Output Colored By Availability")
plt.xlabel("Rated Capacity (MW)")
plt.ylabel("Actual Output (MU)")
plt.grid(True, alpha=0.25)
plt.show()Good color maps for continuous values:
"viridis"
"plasma"
"cividis"
"magma"
"inferno"Avoid using rainbow-style color maps for serious analytical work unless you have a specific reason. They can make differences look stronger than they are.
4. Alpha For Overlapping Points
alpha controls transparency.
Use it when points overlap.
plt.figure(figsize=(8, 5))
plt.scatter(
plants["planned_maintenance_mw"],
plants["unplanned_outage_mw"],
c=plants["emission_score"],
cmap="plasma",
alpha=0.7,
s=90,
)
plt.colorbar(label="Emission Score")
plt.title("Maintenance Load vs Unplanned Outage Load")
plt.xlabel("Planned Maintenance Load (MW)")
plt.ylabel("Unplanned Outage Load (MW)")
plt.grid(True, alpha=0.25)
plt.show()s controls marker size.
alpha=0.7 makes dense regions easier to read.
5. Plot Size
Use figsize when labels, legends, or annotations need room.
plt.figure(figsize=(12, 6))
plt.scatter(
plants["rated_capacity_mw"],
plants["actual_mu"],
c=plants["demand_index"],
cmap="cividis",
s=100,
)
plt.colorbar(label="Demand Index")
plt.title("Large Scatter Plot For Presentation")
plt.xlabel("Rated Capacity (MW)")
plt.ylabel("Actual Output (MU)")
plt.grid(True, alpha=0.25)
plt.show()figsize=(12, 6) means 12 inches wide and 6 inches tall.
For saved images, combine figsize and dpi.
plt.figure(figsize=(12, 6), dpi=140)6. Text Labels
Text labels help identify important points.
Do not label every point unless the chart is very small.
top_capacity = plants.nlargest(5, "rated_capacity_mw")
plt.figure(figsize=(10, 6))
plt.scatter(plants["rated_capacity_mw"], plants["actual_mu"], alpha=0.6)
for _, row in top_capacity.iterrows():
plt.text(
row["rated_capacity_mw"] + 8,
row["actual_mu"],
row["plant_name"],
fontsize=8,
)
plt.title("Top Capacity Plants Labeled")
plt.xlabel("Rated Capacity (MW)")
plt.ylabel("Actual Output (MU)")
plt.grid(True, alpha=0.25)
plt.show()Use plt.text(x, y, label) for simple labels.
7. Annotations
Annotations are better when you want to call out one insight.
high_forced = plants.loc[plants["unplanned_outage_mw"].idxmax()]
plt.figure(figsize=(10, 6))
plt.scatter(
plants["planned_maintenance_mw"],
plants["unplanned_outage_mw"],
c=plants["availability_pct"],
cmap="viridis",
s=90,
)
plt.colorbar(label="Availability (%)")
plt.annotate(
"Highest forced maintenance",
xy=(high_forced["planned_maintenance_mw"], high_forced["unplanned_outage_mw"]),
xytext=(high_forced["planned_maintenance_mw"] - 80, high_forced["unplanned_outage_mw"] + 12),
arrowprops={"arrowstyle": "->", "color": "white"},
)
plt.title("Maintenance Risk View")
plt.xlabel("Planned Maintenance Load (MW)")
plt.ylabel("Unplanned Outage Load (MW)")
plt.grid(True, alpha=0.25)
plt.show()Use annotations to explain why a point matters.
8. Horizontal And Vertical Reference Lines
Reference lines help compare values to an average, target, or threshold.
x_avg = plants["rated_capacity_mw"].mean()
y_avg = plants["actual_mu"].mean()
plt.figure(figsize=(9, 5))
plt.scatter(plants["rated_capacity_mw"], plants["actual_mu"], alpha=0.75)
plt.axvline(x_avg, color="orange", linestyle="--", label="Avg capacity")
plt.axhline(y_avg, color="green", linestyle="--", label="Avg output")
plt.title("Capacity vs Output With Average Lines")
plt.xlabel("Rated Capacity (MW)")
plt.ylabel("Actual Output (MU)")
plt.legend()
plt.grid(True, alpha=0.25)
plt.show()Use:
axvlinefor vertical reference linesaxhlinefor horizontal reference lines
9. Object-Oriented Matplotlib
For advanced plots, prefer fig, ax = plt.subplots().
fig, ax = plt.subplots(figsize=(9, 5))
ax.scatter(plants["rated_capacity_mw"], plants["actual_mu"])
ax.set_title("Object-Oriented Scatter Plot")
ax.set_xlabel("Rated Capacity (MW)")
ax.set_ylabel("Actual Output (MU)")
ax.grid(True, alpha=0.25)
plt.show()This style scales better for subplots.
Important mappings:
plt style | Object-oriented style |
|---|---|
plt.title() | ax.set_title() |
plt.xlabel() | ax.set_xlabel() |
plt.ylabel() | ax.set_ylabel() |
plt.grid() | ax.grid() |
plt.legend() | ax.legend() |
10. Basic Subplots
Create two charts in one row.
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(12, 5))
axes[0].scatter(plants["rated_capacity_mw"], plants["actual_mu"], alpha=0.7)
axes[0].set_title("Capacity vs Output")
axes[0].set_xlabel("Capacity (MW)")
axes[0].set_ylabel("Actual Output (MU)")
axes[0].grid(True, alpha=0.25)
axes[1].scatter(plants["planned_maintenance_mw"], plants["unplanned_outage_mw"], alpha=0.7, color="orange")
axes[1].set_title("Maintenance vs Unplanned Outage Load")
axes[1].set_xlabel("Maintenance (MW)")
axes[1].set_ylabel("Unplanned Outage Load (MW)")
axes[1].grid(True, alpha=0.25)
plt.tight_layout()
plt.show()axes is an array of subplot objects.
11. Subplots With Shared Axes
Use shared axes when charts use the same scale.
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(10, 7), sharex=True)
for ticker, frame in stocks.groupby("ticker"):
axes[0].plot(frame["date"], frame["close"], label=ticker)
axes[1].plot(frame["date"], frame["volume"], label=ticker)
axes[0].set_title("Monthly Close Price")
axes[0].set_ylabel("Close")
axes[0].legend(ncol=5, fontsize=8)
axes[0].grid(True, alpha=0.25)
axes[1].set_title("Monthly Volume")
axes[1].set_xlabel("Date")
axes[1].set_ylabel("Volume")
axes[1].grid(True, alpha=0.25)
plt.tight_layout()
plt.show()sharex=True keeps both charts aligned on the same time axis.
12. 2x2 Dashboard
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 9))
axes[0, 0].scatter(plants["rated_capacity_mw"], plants["actual_mu"], alpha=0.7)
axes[0, 0].set_title("Capacity vs Output")
axes[0, 1].hist(plants["availability_pct"], bins=8, edgecolor="black")
axes[0, 1].set_title("Availability Distribution")
fuel_output = plants.groupby("fuel_type")["actual_mu"].sum().sort_values()
axes[1, 0].barh(fuel_output.index, fuel_output.values)
axes[1, 0].set_title("Output By Fuel Type")
region_maintenance = plants.groupby("region")["planned_maintenance_mw"].mean()
axes[1, 1].bar(region_maintenance.index, region_maintenance.values, color="purple")
axes[1, 1].set_title("Average Maintenance By Region")
axes[1, 1].tick_params(axis="x", rotation=25)
for ax in axes.ravel():
ax.grid(True, alpha=0.2)
plt.tight_layout()
plt.show()Use axes[row, col] for grid layouts.
Use axes.ravel() when you want to loop over every subplot.
13. fig.add_subplot
add_subplot gives you manual control over subplot placement.
fig = plt.figure(figsize=(12, 7))
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 1, 2)
ax1.scatter(plants["rated_capacity_mw"], plants["actual_mu"])
ax1.set_title("Capacity vs Output")
ax2.hist(plants["availability_pct"], bins=8, edgecolor="black")
ax2.set_title("Availability Distribution")
for ticker, frame in stocks.groupby("ticker"):
ax3.plot(frame["date"], frame["close"], label=ticker)
ax3.set_title("Close Price Trend")
ax3.legend(ncol=5, fontsize=8)
plt.tight_layout()
plt.show()The call fig.add_subplot(2, 2, 1) means:
- make a 2-row by 2-column grid
- place this subplot in position 1
14. 3D Scatter Plot
3D plotting requires a 3D projection.
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection="3d")
points = ax.scatter(
plants["rated_capacity_mw"],
plants["planned_maintenance_mw"],
plants["unplanned_outage_mw"],
c=plants["availability_pct"],
cmap="viridis",
s=70,
)
ax.set_title("3D Maintenance View")
ax.set_xlabel("Capacity (MW)")
ax.set_ylabel("Maintenance (MW)")
ax.set_zlabel("Unplanned Outage Load (MW)")
fig.colorbar(points, ax=ax, label="Availability (%)", shrink=0.7)
plt.show()3D charts are useful for exploration, but they can be harder to read in reports.
15. 3D Line Plot
t = np.linspace(0, 8 * np.pi, 250)
x = np.cos(t)
y = np.sin(t)
z = t
fig = plt.figure(figsize=(8, 7))
ax = fig.add_subplot(111, projection="3d")
ax.plot(x, y, z, linewidth=2)
ax.set_title("3D Spiral Line")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("time")
plt.show()3D line plots are good for paths, trajectories, or time-based movement through two measurements.
16. 3D Surface Plot
Surface plots show a computed value over a 2D grid.
x = np.linspace(-4, 4, 80)
y = np.linspace(-4, 4, 80)
xx, yy = np.meshgrid(x, y)
zz = np.sin(xx) + np.cos(yy)
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection="3d")
surface = ax.plot_surface(xx, yy, zz, cmap="viridis", edgecolor="none")
ax.set_title("3D Surface: sin(x) + cos(y)")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
fig.colorbar(surface, ax=ax, shrink=0.7)
plt.show()np.meshgrid creates a coordinate grid.
plot_surface draws the 3D surface.
17. Another Surface Example
x = np.linspace(1, 8, 80)
y = np.linspace(1, 8, 80)
xx, yy = np.meshgrid(x, y)
zz = np.sin(xx) + np.log(yy)
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection="3d")
surface = ax.plot_surface(xx, yy, zz, cmap="plasma", edgecolor="none")
ax.set_title("3D Surface: sin(x) + log(y)")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
fig.colorbar(surface, ax=ax, shrink=0.7)
plt.show()Use valid ranges for functions like log. That is why this example starts at 1, not 0.
18. Contour Plots
A contour plot represents a 3D surface on a 2D plane.
x = np.linspace(-4, 4, 80)
y = np.linspace(-4, 4, 80)
xx, yy = np.meshgrid(x, y)
zz = np.sin(xx) + np.cos(yy)
plt.figure(figsize=(8, 6))
contours = plt.contour(xx, yy, zz, levels=12, cmap="viridis")
plt.clabel(contours, inline=True, fontsize=8)
plt.title("Contour Plot")
plt.xlabel("x")
plt.ylabel("y")
plt.show()Contour lines connect points with equal z values.
19. Filled Contour Plot
plt.figure(figsize=(8, 6))
filled = plt.contourf(xx, yy, zz, levels=20, cmap="viridis")
plt.colorbar(filled, label="z value")
plt.title("Filled Contour Plot")
plt.xlabel("x")
plt.ylabel("y")
plt.show()Use contourf when you want color-filled regions.
20. Heatmap
Heatmaps are useful for matrix-like data.
Example: average actual output by region and fuel type.
heat = plants.pivot_table(
index="region",
columns="fuel_type",
values="actual_mu",
aggfunc="mean",
).fillna(0)
plt.figure(figsize=(8, 5))
plt.imshow(heat, cmap="YlGnBu")
plt.colorbar(label="Average Actual Output (MU)")
plt.xticks(np.arange(len(heat.columns)), heat.columns, rotation=25, ha="right")
plt.yticks(np.arange(len(heat.index)), heat.index)
plt.title("Average Output Heatmap")
plt.tight_layout()
plt.show()imshow displays a 2D matrix as an image.
Use xticks and yticks to make matrix labels readable.
21. Heatmap With Cell Labels
plt.figure(figsize=(8, 5))
plt.imshow(heat, cmap="YlGnBu")
plt.colorbar(label="Average Actual Output (MU)")
plt.xticks(np.arange(len(heat.columns)), heat.columns, rotation=25, ha="right")
plt.yticks(np.arange(len(heat.index)), heat.index)
for row in range(heat.shape[0]):
for col in range(heat.shape[1]):
plt.text(col, row, f"{heat.iloc[row, col]:.0f}", ha="center", va="center", color="black")
plt.title("Average Output Heatmap With Labels")
plt.tight_layout()
plt.show()Cell labels are helpful for small matrices.
For large matrices, labels can become noisy.
22. Pandas .plot()
Pandas can call Matplotlib behind the scenes.
This is useful for quick exploration.
22.1 Series Plot
stocks.groupby("ticker")["close"].mean().sort_values().plot(kind="barh", figsize=(8, 4))
plt.title("Average Close Price By Ticker")
plt.xlabel("Average Close")
plt.tight_layout()
plt.show()Explanation
- Groups stock data by ticker symbol and calculates the mean closing price for each group
- Sorts the results in ascending order to arrange bars from lowest to highest average price
- Generates a horizontal bar chart visualization using matplotlib with specified figure dimensions
- Adds appropriate title and axis labels for clear data presentation
- Applies tight layout formatting to ensure proper spacing and display of chart elements
22.2 DataFrame Line Plot
close_wide = stocks.pivot(index="date", columns="ticker", values="close")
close_wide.plot(figsize=(10, 5), marker="o")
plt.title("Monthly Close Price By Ticker")
plt.xlabel("Date")
plt.ylabel("Close Price")
plt.grid(True, alpha=0.25)
plt.tight_layout()
plt.show()Explanation
- Transforms the stocks DataFrame from long format to wide format using pivot, where dates become rows, tickers become columns, and closing prices are the values
- Generates a line plot with markers showing the monthly closing price trends for each stock ticker over time
- Applies formatting including figure size, title, axis labels, grid lines with transparency, and automatic layout adjustment for better visualization
- Displays the resulting plot to visualize price movements and compare performance across different stock symbols
- Uses matplotlib's plotting functionality to create an interactive chart that helps analyze stock market data patterns
22.3 Pandas Scatter Plot
stocks.plot(
kind="scatter",
x="close",
y="volume",
figsize=(8, 5),
alpha=0.7,
)
plt.title("Close Price vs Volume")
plt.grid(True, alpha=0.25)
plt.show()Explanation
- Generates a scatter plot showing the correlation between stock closing prices (x-axis) and trading volume (y-axis) using pandas plotting functionality
- Sets figure dimensions to 8x5 inches with 70% transparency for data points to improve visibility of overlapping observations
- Adds a title "Close Price vs Volume" and includes a subtle grid overlay with 25% opacity for easier data reading
- Displays the final visualization with plt.show() to render the scatter plot in the output
- Uses matplotlib's plt module for additional formatting elements like titles and grid styling
22.4 Pandas Histogram
stocks["return_pct"].plot(kind="hist", bins=10, edgecolor="black", figsize=(8, 4))
plt.title("Monthly Return Distribution")
plt.xlabel("Return (%)")
plt.show()Explanation
- Plots the distribution of monthly stock returns using a histogram with 10 bins to categorize the data
- Adds black edges around each histogram bar for better visual separation and clarity
- Sets the figure size to 8x4 inches for optimal display of the distribution chart
- Includes appropriate title and x-axis label to clearly communicate what the visualization represents
- Displays the final histogram plot showing how monthly returns are distributed across different percentage ranges
22.5 Pandas Pie Chart
fuel_counts = plants["fuel_type"].value_counts()
fuel_counts.plot(kind="pie", autopct="%0.1f%%", figsize=(6, 6))
plt.title("Fuel Type Share")
plt.ylabel("")
plt.show()Explanation
- The code counts the frequency of each unique fuel type in the plants DataFrame using value_counts() method
- It generates a pie chart visualization showing the percentage distribution of different fuel types with automatic percentage labels
- The chart is configured with a 6x6 figure size and includes a title "Fuel Type Share" without a y-axis label
- The visualization helps identify the relative proportions of various fuel sources used in the power plants dataset
- The resulting pie chart displays each fuel type as a slice representing its share of the total plant fleet
For quick work, Pandas .plot() is convenient.
For polished visuals, the object-oriented Matplotlib API gives more control.
23. Practice Problems
Use the two CSV files from this guide.
Problem 1: Two Subplots With Average Reference Lines
Create a figure with two charts:
- Chart 1:
rated_capacity_mwvsplanned_maintenance_mw - Chart 2:
rated_capacity_mwvsactual_mu - use only the top 5 most frequent regions by row count
- draw average x and y lines on both charts
top_regions = plants["region"].value_counts().head(5).index
sample = plants[plants["region"].isin(top_regions)]
fig, axes = plt.subplots(1, 2, figsize=(13, 5))
axes[0].scatter(sample["rated_capacity_mw"], sample["planned_maintenance_mw"], alpha=0.75)
axes[0].axvline(sample["rated_capacity_mw"].mean(), color="orange", linestyle="--")
axes[0].axhline(sample["planned_maintenance_mw"].mean(), color="green", linestyle="--")
axes[0].set_title("Capacity vs Maintenance")
axes[0].set_xlabel("Rated Capacity (MW)")
axes[0].set_ylabel("Planned Maintenance Load (MW)")
axes[0].grid(True, alpha=0.25)
axes[1].scatter(sample["rated_capacity_mw"], sample["actual_mu"], alpha=0.75, color="purple")
axes[1].axvline(sample["rated_capacity_mw"].mean(), color="orange", linestyle="--")
axes[1].axhline(sample["actual_mu"].mean(), color="green", linestyle="--")
axes[1].set_title("Capacity vs Output")
axes[1].set_xlabel("Rated Capacity (MW)")
axes[1].set_ylabel("Actual Output (MU)")
axes[1].grid(True, alpha=0.25)
plt.tight_layout()
plt.show()Explanation
- Filters the plants dataset to include only the top 5 most common regions based on frequency counts
- Creates two side-by-side scatter plots comparing rated capacity against planned maintenance load and actual output measurements
- Adds mean lines for both x and y axes in each subplot to visualize central tendencies
- Configures plot titles, axis labels, and grid formatting for improved readability and analysis
- Uses matplotlib's subplots functionality to display both visualizations in a single figure layout
Problem 2: 3D Scatter Plot
Create a 3D scatter plot using:
- x:
rated_capacity_mw - y:
planned_maintenance_mw - z:
unplanned_outage_mw - color:
availability_pct
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection="3d")
points = ax.scatter(
plants["rated_capacity_mw"],
plants["planned_maintenance_mw"],
plants["unplanned_outage_mw"],
c=plants["availability_pct"],
cmap="viridis",
s=80,
)
ax.set_title("3D Plant Outage Scatter")
ax.set_xlabel("Capacity (MW)")
ax.set_ylabel("Maintenance (MW)")
ax.set_zlabel("Unplanned Outage Load (MW)")
fig.colorbar(points, ax=ax, shrink=0.7, label="Availability (%)")
plt.show()Explanation
- Creates a 3D visualization showing the relationship between rated capacity, planned maintenance, and unplanned outages for power plants
- Uses color mapping to represent availability percentages across the scatter points, with viridis colormap for clear visual distinction
- Sets appropriate axis labels and title to clearly indicate what each dimension represents in the power plant data
- Adds a colorbar to show the correlation between point colors and availability percentages
- Displays the final 3D scatter plot with properly sized markers and adjusted color bar positioning
Problem 3: Surface Plot
Plot this equation:
z = sin(x) + cos(y)x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
xx, yy = np.meshgrid(x, y)
zz = np.sin(xx) + np.cos(yy)
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection="3d")
surface = ax.plot_surface(xx, yy, zz, cmap="viridis", edgecolor="none")
ax.set_title("Surface: sin(x) + cos(y)")
fig.colorbar(surface, ax=ax, shrink=0.7)
plt.show()Explanation
- Generates a grid of x and y coordinates ranging from -5 to 5 with 100 points each using np.linspace and np.meshgrid
- Computes the z-values as the sum of sine of x values and cosine of y values across the entire grid
- Creates a 3D surface plot using matplotlib's plot_surface function with a viridis color map and removes edge lines for smoother appearance
- Adds a title "Surface: sin(x) + cos(y)" and includes a color bar to indicate z-value intensity levels
- Displays the resulting 3D visualization with proper figure sizing and axis labeling
Problem 4: 3D Contour Plot
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection="3d")
contours = ax.contour3D(xx, yy, zz, 40, cmap="viridis")
ax.set_title("3D Contour: sin(x) + cos(y)")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
plt.show()Explanation
- Creates a 3D figure with specified dimensions (9x7 inches) and adds a 3D subplot using the '3d' projection
- Generates 40 contour levels from the 3D data arrays (xx, yy, zz) using the 'viridis' colormap to visualize the mathematical function sin(x) + cos(y)
- Sets descriptive labels for all three axes (x, y, z) along with a title identifying the plotted function
- Displays the final 3D contour visualization with proper axis labeling and color mapping
Problem 5: Filled 2D Contour Plot
plt.figure(figsize=(8, 6))
filled = plt.contourf(xx, yy, zz, levels=25, cmap="viridis")
plt.colorbar(filled, label="z value")
plt.title("Filled Contour: sin(x) + cos(y)")
plt.xlabel("x")
plt.ylabel("y")
plt.show()Explanation
- Creates a figure window with specified dimensions (8 by 6 inches) for the visualization
- Generates a filled contour plot using contourf() with 25 distinct color levels and the viridis colormap to represent z values
- Adds a color bar legend to show the relationship between colors and z value ranges
- Sets the plot title, x-axis label, and y-axis label for proper documentation and context
- Displays the final contour plot visualization with all configured elements
Problem 6: Use Pandas Plot Functions
Create a line chart of close prices.
close_wide = stocks.pivot(index="date", columns="ticker", values="close")
close_wide.plot(figsize=(10, 5), marker="o")
plt.title("Ticker Close Prices")
plt.xlabel("Date")
plt.ylabel("Close")
plt.grid(True, alpha=0.25)
plt.tight_layout()
plt.show()Explanation
- Transforms the stocks DataFrame from long format to wide format using pivot, where dates become rows, tickers become columns, and closing prices are the values
- Generates a line plot with markers showing the closing price trends for each ticker across the date range
- Applies formatting including figure size, title, axis labels, and grid lines to enhance readability of the financial data visualization
- Uses tight_layout to ensure proper spacing and prevent label cutoff in the final plot display
- Displays the resulting matplotlib chart showing comparative price movements for all tickers over time
Problem 7: Close Price vs Volume For Top 5 Stocks
top_tickers = stocks.groupby("ticker")["volume"].sum().nlargest(5).index
sample = stocks[stocks["ticker"].isin(top_tickers)]
fig, ax = plt.subplots(figsize=(9, 6))
for ticker, frame in sample.groupby("ticker"):
ax.scatter(frame["close"], frame["volume"], label=ticker, alpha=0.75)
ax.set_title("Close Price vs Volume")
ax.set_xlabel("Close Price")
ax.set_ylabel("Volume")
ax.legend()
ax.grid(True, alpha=0.25)
plt.show()Explanation
- Identifies the top 5 stock tickers with highest total trading volume using groupby aggregation and nlargest
- Filters the original dataset to include only records from these top volume tickers
- Creates a scatter plot showing the relationship between closing price and trading volume for each stock
- Applies visual styling including transparency, legends, and grid lines for better data visualization
- Displays the resulting plot with appropriate axis labels and title for clear interpretation
Problem 8: 3D Scatter With Synthetic Time Data
time = np.linspace(0, 20, 200)
x = np.sin(time)
y = np.cos(time)
z = time
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection="3d")
points = ax.scatter(x, y, z, c=z, cmap="plasma")
ax.set_title("3D Time Path")
ax.set_xlabel("sin(time)")
ax.set_ylabel("cos(time)")
ax.set_zlabel("time")
fig.colorbar(points, ax=ax, shrink=0.7, label="time")
plt.show()Explanation
- Generates a time array from 0 to 20 seconds with 200 evenly spaced points using numpy's linspace function
- Calculates x, y, and z coordinates as sine, cosine, and time values respectively to create a helical path in 3D space
- Creates a 3D scatter plot using matplotlib's 3D projection where color mapping represents the time parameter along the path
- Adds proper axis labels and a colorbar to show the time progression through the visualization
- Displays the resulting 3D plot showing how sine and cosine values trace out a circular path while time increases linearly
Problem 9: Surface And Contours For A Radial Function
x = np.linspace(-6, 6, 120)
y = np.linspace(-6, 6, 120)
xx, yy = np.meshgrid(x, y)
r = np.sqrt(xx**2 + yy**2)
zz = np.sin(r)
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection="3d")
ax.plot_surface(xx, yy, zz, cmap="magma", edgecolor="none")
ax.set_title("Surface: sin(radius)")
plt.show()
plt.figure(figsize=(8, 6))
plt.contour(xx, yy, zz, levels=18, cmap="magma")
plt.title("Contour: sin(radius)")
plt.xlabel("x")
plt.ylabel("y")
plt.show()
plt.figure(figsize=(8, 6))
plt.contourf(xx, yy, zz, levels=25, cmap="magma")
plt.colorbar(label="z value")
plt.title("Filled Contour: sin(radius)")
plt.xlabel("x")
plt.ylabel("y")
plt.show()Explanation
- Generates a grid of x and y coordinates spanning from -6 to 6 with 120 points each using numpy's linspace function
- Calculates the radial distance from origin for each point and computes the z values using the sine of radius formula
- Creates three visualizations showing the same mathematical function: a 3D surface plot, a 2D contour plot, and a filled contour plot
- Uses matplotlib's plotting functions to display the mathematical relationship between x, y, and z coordinates in different visual formats
- Applies the magma colormap to all plots to provide color gradients that enhance visualization of the function's variation
Problem 10: Surface And Contours For A Log Function
x = np.linspace(1, 10, 120)
y = np.linspace(1, 10, 120)
xx, yy = np.meshgrid(x, y)
zz = np.log(xx) + np.sqrt(yy)
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection="3d")
ax.plot_surface(xx, yy, zz, cmap="cividis", edgecolor="none")
ax.set_title("Surface: log(x) + sqrt(y)")
plt.show()
plt.figure(figsize=(8, 6))
plt.contour(xx, yy, zz, levels=18, cmap="cividis")
plt.title("Contour: log(x) + sqrt(y)")
plt.xlabel("x")
plt.ylabel("y")
plt.show()
plt.figure(figsize=(8, 6))
plt.contourf(xx, yy, zz, levels=25, cmap="cividis")
plt.colorbar(label="z value")
plt.title("Filled Contour: log(x) + sqrt(y)")
plt.xlabel("x")
plt.ylabel("y")
plt.show()Explanation
- Generates a grid of x and y values using linspace and meshgrid to create coordinate arrays for plotting
- Computes z values using the mathematical function log(x) + sqrt(y) across the entire grid domain
- Creates three different visualizations including a 3D surface plot, a contour plot, and a filled contour plot with consistent color mapping
- Uses matplotlib's 3D projection capabilities to render the surface plot with smooth shading and proper axis labeling
- Implements multiple contour visualization techniques with varying level counts and color schemes to show different aspects of the function's behavior
24. Advanced Matplotlib Checklist
You are ready to move forward when you can:
- explain when color should represent a third variable
- add a colorbar when using continuous colors
- use
alphafor overlapping points - annotate one important point without cluttering the plot
- draw average or threshold lines
- create subplots with one row, one column, and grids
- use
sharexandsharey - build 3D scatter and surface plots
- convert surfaces into contour plots
- create a labeled heatmap
- use Pandas
.plot()for quick exploration - decide when a complex chart is useful and when it is just decoration
Advanced visualization is not about making charts look complicated.
It is about showing more context without making the reader work harder.
