DataScience / Visualization /index.html
AashishAIHub's picture
feat: Update all modules with latest UI enhancements and content
13d9acc
raw
history blame
30.4 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Data Visualization Masterclass</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="app flex">
<!-- Sidebar Navigation -->
<aside class="sidebar" id="sidebar">
<h1 class="sidebar__title">πŸ“Š Data Visualization</h1>
<nav>
<h3 class="sidebar__section">Foundations</h3>
<ul class="nav__list" id="navList">
<li><a href="#intro" class="nav__link">🎯 Why Visualize Data?</a></li>
<li><a href="#perception" class="nav__link">πŸ‘οΈ Visual Perception</a></li>
<li><a href="#grammar" class="nav__link">πŸ“ Grammar of Graphics</a></li>
<li><a href="#choosing-charts" class="nav__link">🎨 Choosing the Right Chart</a></li>
</ul>
<h3 class="sidebar__section">Matplotlib Essentials</h3>
<ul class="nav__list">
<li><a href="#matplotlib-anatomy" class="nav__link">πŸ”¬ Figure Anatomy</a></li>
<li><a href="#basic-plots" class="nav__link">πŸ“ˆ Basic Plots</a></li>
<li><a href="#subplots" class="nav__link">πŸ”² Subplots & Layouts</a></li>
<li><a href="#styling" class="nav__link">🎨 Styling & Themes</a></li>
</ul>
<h3 class="sidebar__section">Seaborn Statistical Viz</h3>
<ul class="nav__list">
<li><a href="#seaborn-intro" class="nav__link">🌊 Seaborn Overview</a></li>
<li><a href="#distributions" class="nav__link">πŸ“Š Distribution Plots</a></li>
<li><a href="#relationships" class="nav__link">πŸ”— Relationship Plots</a></li>
<li><a href="#categorical" class="nav__link">πŸ“¦ Categorical Plots</a></li>
<li><a href="#heatmaps" class="nav__link">πŸ”₯ Heatmaps & Clusters</a></li>
</ul>
<h3 class="sidebar__section">Interactive Visualization</h3>
<ul class="nav__list">
<li><a href="#plotly" class="nav__link">πŸš€ Plotly Express</a></li>
<li><a href="#animations" class="nav__link">🎬 Animations</a></li>
<li><a href="#dashboards" class="nav__link">πŸ“± Dashboards (Streamlit)</a></li>
</ul>
<h3 class="sidebar__section">Advanced Topics</h3>
<ul class="nav__list">
<li><a href="#geospatial" class="nav__link">πŸ—ΊοΈ Geospatial Viz</a></li>
<li><a href="#3d-plots" class="nav__link">🎲 3D Visualization</a></li>
<li><a href="#storytelling" class="nav__link">πŸ“– Data Storytelling</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="content" id="content">
<!-- ============================ 1. INTRO ============================ -->
<section id="intro" class="topic-section">
<h2>🎯 Why Visualize Data?</h2>
<p>Data visualization transforms abstract numbers into visual stories. The human brain processes images 60,000Γ—
faster than text. Visualization helps us <strong>explore</strong>, <strong>analyze</strong>, and
<strong>communicate</strong> data effectively.</p>
<div class="info-card">
<strong>Anscombe's Quartet:</strong> Four datasets with nearly identical statistical properties (mean,
variance, correlation) that look completely different when plotted. This demonstrates why visualization is
essential - statistics alone can be misleading!
</div>
<div class="canvas-wrapper">
<canvas id="canvas-anscombe" width="800" height="400"></canvas>
</div>
<h3>Three Purposes of Visualization</h3>
<div class="info-card">
<strong>1. Exploratory:</strong> Discover patterns, anomalies, and insights in your data<br>
<strong>2. Explanatory:</strong> Communicate findings to stakeholders clearly<br>
<strong>3. Confirmatory:</strong> Verify hypotheses and validate models
</div>
<div class="callout callout--insight">πŸ’‘ "The greatest value of a picture is when it forces us to notice what we
never expected to see." β€” John Tukey</div>
<div class="callout callout--tip">βœ… Always start with visualization before building ML models.</div>
</section>
<!-- ====================== 2. VISUAL PERCEPTION ================== -->
<section id="perception" class="topic-section">
<h2>πŸ‘οΈ Visual Perception & Pre-attentive Attributes</h2>
<p>The human visual system can detect certain visual attributes almost instantly (< 250ms) without conscious
effort. These are called <strong>pre-attentive attributes</strong>.</p>
<div class="info-card">
<strong>Pre-attentive Attributes:</strong>
<ul>
<li><strong>Position:</strong> Most accurate for quantitative data (use X/Y axes)</li>
<li><strong>Length:</strong> Bar charts leverage this effectively</li>
<li><strong>Color Hue:</strong> Best for categorical distinctions</li>
<li><strong>Color Intensity:</strong> Good for gradients/magnitude</li>
<li><strong>Size:</strong> Bubble charts, but humans underestimate area</li>
<li><strong>Shape:</strong> Useful for categories, but limit to 5-7 shapes</li>
<li><strong>Orientation:</strong> Lines, angles</li>
</ul>
</div>
<div class="form-group">
<button id="btn-position" class="btn btn--primary">Position Encoding</button>
<button id="btn-color" class="btn btn--primary">Color Encoding</button>
<button id="btn-size" class="btn btn--primary">Size Encoding</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-perception" width="700" height="350"></canvas>
</div>
<h3>Cleveland & McGill's Accuracy Ranking</h3>
<div class="info-card">
<strong>Most Accurate β†’ Least Accurate:</strong><br>
1. Position on common scale (bar chart)<br>
2. Position on non-aligned scale (multiple axes)<br>
3. Length (bar)<br>
4. Angle, Slope<br>
5. Area<br>
6. Volume, Curvature<br>
7. Color saturation, Color hue
</div>
<div class="callout callout--mistake">⚠️ Pie charts use angle (low accuracy). Bar charts are almost always
better!</div>
<div class="callout callout--tip">βœ… Use position for most important data, color for categories.</div>
</section>
<!-- ====================== 3. GRAMMAR OF GRAPHICS ================== -->
<section id="grammar" class="topic-section">
<h2>πŸ“ The Grammar of Graphics</h2>
<p>The Grammar of Graphics (Wilkinson, 1999) is a framework for describing statistical graphics. It's the
foundation of ggplot2 (R) and influences Seaborn, Altair, and Plotly.</p>
<div class="info-card">
<strong>Components of a Graphic:</strong>
<ul>
<li><strong>Data:</strong> The dataset being visualized</li>
<li><strong>Aesthetics (aes):</strong> Mapping data to visual properties (x, y, color, size)</li>
<li><strong>Geometries (geom):</strong> Visual elements (points, lines, bars, areas)</li>
<li><strong>Facets:</strong> Subplots by categorical variable</li>
<li><strong>Statistics:</strong> Transformations (binning, smoothing, aggregation)</li>
<li><strong>Coordinates:</strong> Cartesian, polar, map projections</li>
<li><strong>Themes:</strong> Non-data visual elements (fonts, backgrounds)</li>
</ul>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-grammar" width="800" height="400"></canvas>
</div>
<div class="callout callout--insight">πŸ’‘ Understanding Grammar of Graphics makes you a better visualizer in ANY
library.</div>
</section>
<!-- ====================== 4. CHOOSING CHARTS ================== -->
<section id="choosing-charts" class="topic-section">
<h2>🎨 Choosing the Right Chart</h2>
<p>The best visualization depends on your <strong>data type</strong> and <strong>question</strong>. Here's a
decision guide:</p>
<div class="info-card">
<strong>Single Variable (Univariate):</strong><br>
β€’ Continuous: Histogram, KDE, Box plot, Violin plot<br>
β€’ Categorical: Bar chart, Count plot<br><br>
<strong>Two Variables (Bivariate):</strong><br>
β€’ Both Continuous: Scatter plot, Line chart, Hexbin, 2D histogram<br>
β€’ Continuous + Categorical: Box plot, Violin, Strip, Swarm<br>
β€’ Both Categorical: Heatmap, Grouped bar chart<br><br>
<strong>Multiple Variables (Multivariate):</strong><br>
β€’ Pair plot (scatterplot matrix)<br>
β€’ Parallel coordinates<br>
β€’ Heatmap correlation matrix<br>
β€’ Faceted plots (small multiples)
</div>
<div class="form-group">
<button id="btn-comparison" class="btn btn--primary">Comparison</button>
<button id="btn-composition" class="btn btn--primary">Composition</button>
<button id="btn-distribution" class="btn btn--primary">Distribution</button>
<button id="btn-relationship" class="btn btn--primary">Relationship</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-choosing" width="800" height="400"></canvas>
</div>
<h3>Common Chart Mistakes</h3>
<div class="callout callout--mistake">⚠️ <strong>Pie charts for many categories</strong> - Use bar chart instead
</div>
<div class="callout callout--mistake">⚠️ <strong>3D effects on 2D data</strong> - Distorts perception</div>
<div class="callout callout--mistake">⚠️ <strong>Truncated Y-axis</strong> - Exaggerates differences</div>
<div class="callout callout--mistake">⚠️ <strong>Rainbow color scales</strong> - Not perceptually uniform</div>
</section>
<!-- ====================== 5. MATPLOTLIB ANATOMY ================== -->
<section id="matplotlib-anatomy" class="topic-section">
<h2>πŸ”¬ Matplotlib Figure Anatomy</h2>
<p>Understanding Matplotlib's object hierarchy is key to creating professional visualizations.</p>
<div class="info-card">
<strong>Hierarchical Structure:</strong><br>
<code>Figure β†’ Axes β†’ Axis β†’ Tick β†’ Label</code><br><br>
β€’ <strong>Figure:</strong> The overall window/canvas<br>
β€’ <strong>Axes:</strong> The actual plot area (NOT the X/Y axis!)<br>
β€’ <strong>Axis:</strong> The X or Y axis with ticks and labels<br>
β€’ <strong>Artist:</strong> Everything visible (lines, text, patches)
</div>
<div class="canvas-wrapper">
<canvas id="canvas-anatomy" width="800" height="500"></canvas>
</div>
<h3>Two Interfaces</h3>
<div class="info-card">
<strong>1. pyplot (MATLAB-style):</strong> Quick, implicit state<br>
<code>plt.plot(x, y)</code><br>
<code>plt.xlabel('Time')</code><br>
<code>plt.show()</code><br><br>
<strong>2. Object-Oriented (OO):</strong> Explicit, recommended for complex plots<br>
<code>fig, ax = plt.subplots()</code><br>
<code>ax.plot(x, y)</code><br>
<code>ax.set_xlabel('Time')</code>
</div>
<div class="callout callout--tip">βœ… Always use OO interface for publication-quality plots.</div>
</section>
<!-- ====================== 6. BASIC PLOTS ================== -->
<section id="basic-plots" class="topic-section">
<h2>πŸ“ˆ Basic Matplotlib Plots</h2>
<p>Master the fundamental plot types that form the foundation of data visualization.</p>
<div class="form-group">
<button id="btn-line" class="btn btn--primary">Line Plot</button>
<button id="btn-scatter" class="btn btn--primary">Scatter Plot</button>
<button id="btn-bar" class="btn btn--primary">Bar Chart</button>
<button id="btn-hist" class="btn btn--primary">Histogram</button>
<button id="btn-pie" class="btn btn--primary">Pie Chart</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-basic" width="800" height="400"></canvas>
</div>
<h3>Code Examples</h3>
<div class="info-card">
<strong>Line Plot:</strong><br>
<code>ax.plot(x, y, color='blue', linestyle='--', marker='o', label='Series A')</code><br><br>
<strong>Scatter Plot:</strong><br>
<code>ax.scatter(x, y, c=colors, s=sizes, alpha=0.7, cmap='viridis')</code><br><br>
<strong>Bar Chart:</strong><br>
<code>ax.bar(categories, values, color='steelblue', edgecolor='black')</code><br><br>
<strong>Histogram:</strong><br>
<code>ax.hist(data, bins=30, edgecolor='white', density=True)</code>
</div>
</section>
<!-- ====================== 7. SUBPLOTS ================== -->
<section id="subplots" class="topic-section">
<h2>πŸ”² Subplots & Multi-panel Layouts</h2>
<p>Combine multiple visualizations into a single figure for comprehensive analysis.</p>
<div class="form-group">
<button id="btn-grid-2x2" class="btn btn--primary">2Γ—2 Grid</button>
<button id="btn-grid-uneven" class="btn btn--primary">Uneven Grid</button>
<button id="btn-gridspec" class="btn btn--primary">GridSpec</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-subplots" width="800" height="500"></canvas>
</div>
<div class="info-card">
<strong>Methods:</strong><br>
<code>fig, axes = plt.subplots(2, 2, figsize=(12, 10))</code><br>
<code>fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)</code><br>
<code>gs = fig.add_gridspec(3, 3); ax = fig.add_subplot(gs[0, :])</code>
</div>
<div class="callout callout--tip">βœ… Use plt.tight_layout() or fig.set_constrained_layout(True) to prevent
overlaps.</div>
</section>
<!-- ====================== 8. STYLING ================== -->
<section id="styling" class="topic-section">
<h2>🎨 Styling & Professional Themes</h2>
<p>Transform basic plots into publication-quality visualizations.</p>
<div class="form-group">
<button id="btn-style-default" class="btn btn--primary">Default</button>
<button id="btn-style-seaborn" class="btn btn--primary">Seaborn</button>
<button id="btn-style-ggplot" class="btn btn--primary">ggplot</button>
<button id="btn-style-dark" class="btn btn--primary">Dark Background</button>
<button id="btn-style-538" class="btn btn--primary">FiveThirtyEight</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-styling" width="800" height="400"></canvas>
</div>
<div class="info-card">
<strong>Available Styles:</strong><br>
<code>plt.style.available</code> β†’ Lists all built-in styles<br>
<code>plt.style.use('seaborn-v0_8-whitegrid')</code><br>
<code>with plt.style.context('dark_background'):</code>
</div>
<h3>Color Palettes</h3>
<div class="info-card">
<strong>Perceptually Uniform:</strong> viridis, plasma, inferno, magma, cividis<br>
<strong>Sequential:</strong> Blues, Greens, Oranges (for magnitude)<br>
<strong>Diverging:</strong> coolwarm, RdBu (for +/- deviations)<br>
<strong>Categorical:</strong> tab10, Set2, Paired (discrete groups)
</div>
</section>
<!-- ====================== 9. SEABORN INTRO ================== -->
<section id="seaborn-intro" class="topic-section">
<h2>🌊 Seaborn: Statistical Visualization</h2>
<p>Seaborn is a high-level library built on Matplotlib that makes statistical graphics beautiful and easy.</p>
<div class="info-card">
<strong>Why Seaborn?</strong>
<ul>
<li>Beautiful default styles and color palettes</li>
<li>Works seamlessly with Pandas DataFrames</li>
<li>Statistical estimation built-in (confidence intervals, regression)</li>
<li>Faceting for multi-panel figures</li>
<li>Functions organized by plot purpose</li>
</ul>
</div>
<h3>Seaborn Function Categories</h3>
<div class="info-card">
<strong>Figure-level:</strong> Create entire figures (displot, relplot, catplot)<br>
<strong>Axes-level:</strong> Draw on specific axes (histplot, scatterplot, boxplot)<br><br>
<strong>By Purpose:</strong><br>
β€’ <strong>Distribution:</strong> histplot, kdeplot, ecdfplot, rugplot<br>
β€’ <strong>Relationship:</strong> scatterplot, lineplot, regplot<br>
β€’ <strong>Categorical:</strong> stripplot, swarmplot, boxplot, violinplot, barplot<br>
β€’ <strong>Matrix:</strong> heatmap, clustermap
</div>
<div class="canvas-wrapper">
<canvas id="canvas-seaborn-intro" width="800" height="400"></canvas>
</div>
</section>
<!-- ====================== 10. DISTRIBUTIONS ================== -->
<section id="distributions" class="topic-section">
<h2>πŸ“Š Distribution Plots</h2>
<p>Visualize the distribution of a single variable or compare distributions across groups.</p>
<div class="form-group">
<button id="btn-histplot" class="btn btn--primary">Histogram</button>
<button id="btn-kdeplot" class="btn btn--primary">KDE Plot</button>
<button id="btn-ecdfplot" class="btn btn--primary">ECDF</button>
<button id="btn-rugplot" class="btn btn--primary">Rug Plot</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-distributions" width="800" height="400"></canvas>
</div>
<div class="info-card">
<strong>Histogram vs KDE:</strong><br>
β€’ Histogram: Discrete bins, shows raw counts<br>
β€’ KDE: Smooth curve, estimates probability density<br>
β€’ Use both together: <code>sns.histplot(data, kde=True)</code>
</div>
<div class="callout callout--insight">πŸ’‘ ECDF (Empirical Cumulative Distribution Function) avoids binning issues
entirely.</div>
</section>
<!-- ====================== 11. RELATIONSHIPS ================== -->
<section id="relationships" class="topic-section">
<h2>πŸ”— Relationship Plots</h2>
<p>Explore relationships between two or more continuous variables.</p>
<div class="form-group">
<button id="btn-scatter-hue" class="btn btn--primary">Scatter + Hue</button>
<button id="btn-regplot" class="btn btn--primary">Regression Plot</button>
<button id="btn-residplot" class="btn btn--primary">Residual Plot</button>
<button id="btn-pairplot" class="btn btn--primary">Pair Plot</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-relationships" width="800" height="500"></canvas>
</div>
<div class="info-card">
<strong>Key Functions:</strong><br>
<code>sns.scatterplot(data=df, x='x', y='y', hue='category', size='magnitude')</code><br>
<code>sns.regplot(data=df, x='x', y='y', scatter_kws={'alpha':0.5})</code><br>
<code>sns.pairplot(df, hue='species', diag_kind='kde')</code>
</div>
</section>
<!-- ====================== 12. CATEGORICAL ================== -->
<section id="categorical" class="topic-section">
<h2>πŸ“¦ Categorical Plots</h2>
<p>Visualize distributions and comparisons across categorical groups.</p>
<div class="form-group">
<button id="btn-stripplot" class="btn btn--primary">Strip Plot</button>
<button id="btn-swarmplot" class="btn btn--primary">Swarm Plot</button>
<button id="btn-boxplot" class="btn btn--primary">Box Plot</button>
<button id="btn-violinplot" class="btn btn--primary">Violin Plot</button>
<button id="btn-barplot" class="btn btn--primary">Bar Plot</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-categorical" width="800" height="400"></canvas>
</div>
<div class="info-card">
<strong>When to Use:</strong><br>
β€’ <strong>Strip/Swarm:</strong> Show all data points (small datasets)<br>
β€’ <strong>Box:</strong> Summary statistics (median, quartiles, outliers)<br>
β€’ <strong>Violin:</strong> Full distribution shape + summary<br>
β€’ <strong>Bar:</strong> Mean/count with error bars
</div>
</section>
<!-- ====================== 13. HEATMAPS ================== -->
<section id="heatmaps" class="topic-section">
<h2>πŸ”₯ Heatmaps & Correlation Matrices</h2>
<p>Visualize matrices of values using color intensity. Essential for EDA correlation analysis.</p>
<div class="form-group">
<button id="btn-heatmap-basic" class="btn btn--primary">Basic Heatmap</button>
<button id="btn-corr-matrix" class="btn btn--primary">Correlation Matrix</button>
<button id="btn-clustermap" class="btn btn--primary">Clustermap</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-heatmaps" width="800" height="500"></canvas>
</div>
<div class="info-card">
<strong>Best Practices:</strong><br>
β€’ Always annotate with values: <code>annot=True</code><br>
β€’ Use diverging colormap for correlation: <code>cmap='coolwarm', center=0</code><br>
β€’ Mask upper/lower triangle: <code>mask=np.triu(np.ones_like(corr))</code><br>
β€’ Square cells: <code>square=True</code>
</div>
<div class="callout callout--insight">πŸ’‘ Clustermap automatically clusters similar rows/columns together.</div>
</section>
<!-- ====================== 14. PLOTLY ================== -->
<section id="plotly" class="topic-section">
<h2>πŸš€ Plotly Express: Interactive Visualization</h2>
<p>Plotly creates interactive, web-based visualizations with zoom, pan, hover tooltips, and more.</p>
<div class="info-card">
<strong>Why Plotly?</strong>
<ul>
<li>Interactive out of the box (zoom, pan, select)</li>
<li>Hover tooltips with data details</li>
<li>Export as HTML, PNG, or embed in dashboards</li>
<li>Works in Jupyter, Streamlit, Dash</li>
<li>plotly.express is the high-level API (like Seaborn for Matplotlib)</li>
</ul>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-plotly" width="800" height="400"></canvas>
</div>
<div class="info-card">
<strong>Common Functions:</strong><br>
<code>px.scatter(df, x='x', y='y', color='category', size='value', hover_data=['name'])</code><br>
<code>px.line(df, x='date', y='price', color='stock')</code><br>
<code>px.bar(df, x='category', y='count', color='group', barmode='group')</code><br>
<code>px.histogram(df, x='value', nbins=50, marginal='box')</code>
</div>
</section>
<!-- ====================== 15. ANIMATIONS ================== -->
<section id="animations" class="topic-section">
<h2>🎬 Animated Visualizations</h2>
<p>Add time dimension to your visualizations with animations.</p>
<div class="form-group">
<button id="btn-animate" class="btn btn--primary">β–Ά Play Animation</button>
<button id="btn-stop" class="btn btn--primary">⏹ Stop</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-animation" width="800" height="400"></canvas>
</div>
<div class="info-card">
<strong>Plotly Animation:</strong><br>
<code>px.scatter(df, x='gdp', y='life_exp', animation_frame='year', animation_group='country', size='pop', color='continent')</code><br><br>
<strong>Matplotlib Animation:</strong><br>
<code>from matplotlib.animation import FuncAnimation</code><br>
<code>ani = FuncAnimation(fig, update_func, frames=100, interval=50)</code>
</div>
<div class="callout callout--tip">βœ… Hans Rosling's Gapminder is the classic example of animated scatter plots!
</div>
</section>
<!-- ====================== 16. DASHBOARDS ================== -->
<section id="dashboards" class="topic-section">
<h2>πŸ“± Interactive Dashboards with Streamlit</h2>
<p>Build interactive web apps for data exploration without web development experience.</p>
<div class="info-card">
<strong>Streamlit Basics:</strong><br>
<code>streamlit run app.py</code><br><br>
<code>import streamlit as st</code><br>
<code>st.title("My Dashboard")</code><br>
<code>st.slider("Select value", 0, 100, 50)</code><br>
<code>st.selectbox("Choose", ["A", "B", "C"])</code><br>
<code>st.plotly_chart(fig)</code>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-dashboard" width="800" height="400"></canvas>
</div>
<div class="callout callout--insight">πŸ’‘ Streamlit auto-reruns when input changes - no callbacks needed!</div>
</section>
<!-- ====================== 17. GEOSPATIAL ================== -->
<section id="geospatial" class="topic-section">
<h2>πŸ—ΊοΈ Geospatial Visualization</h2>
<p>Visualize geographic data with maps, choropleth, and point plots.</p>
<div class="form-group">
<button id="btn-choropleth" class="btn btn--primary">Choropleth Map</button>
<button id="btn-scatter-geo" class="btn btn--primary">Scatter on Map</button>
<button id="btn-heatmap-geo" class="btn btn--primary">Density Map</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-geo" width="800" height="500"></canvas>
</div>
<div class="info-card">
<strong>Libraries:</strong><br>
β€’ <strong>Plotly:</strong> <code>px.choropleth(df, locations='country', color='value')</code><br>
β€’ <strong>Folium:</strong> Interactive Leaflet maps<br>
β€’ <strong>Geopandas + Matplotlib:</strong> Static maps with shapefiles<br>
β€’ <strong>Kepler.gl:</strong> Large-scale geospatial visualization
</div>
</section>
<!-- ====================== 18. 3D PLOTS ================== -->
<section id="3d-plots" class="topic-section">
<h2>🎲 3D Visualization</h2>
<p>Visualize three-dimensional relationships with surface plots, scatter plots, and more.</p>
<div class="form-group">
<button id="btn-3d-scatter" class="btn btn--primary">3D Scatter</button>
<button id="btn-3d-surface" class="btn btn--primary">Surface Plot</button>
<button id="btn-3d-wireframe" class="btn btn--primary">Wireframe</button>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-3d" width="800" height="500"></canvas>
</div>
<div class="callout callout--mistake">⚠️ 3D plots can obscure data. Often, multiple 2D views are more effective.
</div>
<div class="callout callout--tip">βœ… Use Plotly for interactive 3D (rotate, zoom) instead of static Matplotlib
3D.</div>
</section>
<!-- ====================== 19. STORYTELLING ================== -->
<section id="storytelling" class="topic-section">
<h2>πŸ“– Data Storytelling</h2>
<p>Transform visualizations into compelling narratives that drive action.</p>
<div class="info-card">
<strong>The Data Storytelling Framework:</strong>
<ol>
<li><strong>Context:</strong> Why does this matter? Who is the audience?</li>
<li><strong>Data:</strong> What insights did you discover?</li>
<li><strong>Narrative:</strong> What's the storyline (beginning, middle, end)?</li>
<li><strong>Visual:</strong> Which chart best supports the story?</li>
<li><strong>Call to Action:</strong> What should the audience do?</li>
</ol>
</div>
<div class="canvas-wrapper">
<canvas id="canvas-storytelling" width="800" height="400"></canvas>
</div>
<h3>Design Principles</h3>
<div class="info-card">
<strong>Remove Clutter:</strong> Eliminate chartjunk, gridlines, borders<br>
<strong>Focus Attention:</strong> Use color strategically (grey + accent)<br>
<strong>Think Like a Designer:</strong> Alignment, white space, hierarchy<br>
<strong>Tell a Story:</strong> Title = conclusion, not description<br>
<strong>Bad:</strong> "Sales by Region"<br>
<strong>Good:</strong> "West Region Sales Dropped 23% in Q4"
</div>
<div class="callout callout--insight">πŸ’‘ "If you can't explain it simply, you don't understand it well enough."
β€” Einstein</div>
<div class="callout callout--tip">βœ… Read "Storytelling with Data" by Cole Nussbaumer Knaflic</div>
</section>
<!-- Footer -->
<footer
style="text-align: center; padding: 40px 20px; border-top: 1px solid var(--border-color); margin-top: 60px;">
<p style="color: var(--text-secondary);">πŸ“Š Data Visualization Masterclass | Part of the Data Science & AI
Curriculum</p>
<a href="../index.html" class="btn btn--primary" style="margin-top: 16px;">← Back to Home</a>
</footer>
</main>
</div>
<script src="app.js"></script>
</body>
</html>