# Mastering Advanced Matplotlib: Visualizations and Techniques URL: https://madhudadi.in/blog/posts/advanced-matplotlib-techniques-for-data-visualization Published: 2026-06-09 Tags: Matplotlib, python Read time: 55 min Difficulty: intermediate > Go beyond basic charts with advanced Matplotlib: colored scatter plots, colorbars, annotations, reference lines, subplots, 3D charts, contour plots, heatmaps, and Pandas plotting.# 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.csv` - `matplotlib_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 `alpha` to handle overlapping points - change figure size and resolution - place text labels on selected points - annotate specific insights with arrows - add `axhline` and `axvline` reference lines - create one-row, one-column, and grid subplots - use `sharex` and `sharey` - 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 ```python import numpy as np import pandas as pd import matplotlib.pyplot as plt ``` Load the datasets: ```python 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 ```python 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. ```python 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: ```python "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. ```python 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. ```python 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`. ```python 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. ```python 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. ```python 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. ```python 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: - `axvline` for vertical reference lines - `axhline` for horizontal reference lines ## 9. Object-Oriented Matplotlib For advanced plots, prefer `fig, ax = plt.subplots()`. ```python 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. ```python 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. ```python 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 ```python 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. ```python 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. ```python 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 ```python 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. ```python 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 ```python 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. ```python 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 ```python 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. ```python 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 ```python 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 ```python 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 ```python 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 ```python 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 ```python 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 ```python 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_mw` vs `planned_maintenance_mw` - Chart 2: `rated_capacity_mw` vs `actual_mu` - use only the top 5 most frequent regions by row count - draw average x and y lines on both charts ```python 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` ```python 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: ```text z = sin(x) + cos(y) ``` ```python 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 ```python 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 ```python 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. ```python 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 ```python 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 ```python 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 ```python 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 ```python 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 `alpha` for 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 `sharex` and `sharey` - 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.