S
Saurav Danej
90-Day AI/ML LinkedIn Content System
← All days
33
Day 33 of 90AI/ML

Plotting — the chart that ends every EDA

POST 1 of 5 MorningAI/MLConcept

matplotlib is the engine. Everything else is a wrapper.

Plot libraries in Python are confusing because there are many of them and most overlap. The simplifying frame — matplotlib is the engine. Almost everything else is a layer that ultimately renders through matplotlib (or to web with a similar abstraction).

Seaborn — high-level statistical plotting. Box plots, violin plots, regression plots, pair plots. Renders through matplotlib. Use when you want statistical-looking output without configuring axes by hand.

Pandas .plot() — convenience method that wraps matplotlib for quick DataFrame visualisation. df.plot(kind='line') gives you a quick line chart. Used for sanity checks during exploratory work.

Plotnine — a Python implementation of ggplot2's grammar of graphics. Different mental model (layer-based composition); same final pixels.

Plotly — interactive plots. Renders to JavaScript / WebGL in the browser, not matplotlib. Use when you need zoomable, hoverable charts in dashboards or notebooks.

Bokeh — alternative to plotly. Similar interactive philosophy.

Altair — declarative grammar based on Vega-Lite. Renders to web.

My daily workflow:

Quick sanity plots during analysis — df.plot() or df.hist(). Fast, no config.

Statistical plots for reports and EDA — seaborn (sns.histplot, sns.boxplot, sns.pairplot). Tidy long-form data, nice defaults.

Final polished plots for slides or papers — matplotlib direct. Full control over axes, fonts, colors, annotations.

Interactive dashboards — plotly. Zoomable time series, hoverable scatter plots, drill-down.

The rule — learn matplotlib's basics once. The rest sit on top, and you can switch between them based on what you need.

Don't get lost in the proliferation of libraries. matplotlib is the engine; everything else is a stylistic preference or a different output target.
#NumPy#Pandas#DataScience#Python#100DaysOfCode#Matplotlib
POST 2 of 5 MiddayAI/MLDeep dive

Pair plot — the chart I make first, every dataset

Drop a fresh dataset on me and I run sns.pairplot() before anything else.

The pair plot is a grid of small charts. The diagonal shows the distribution of each numeric column (histogram or kde). The off-diagonal shows scatter plots of each pair of columns. With hue=class for classification problems, the colors split each chart by class.

In 2 seconds you spot:

Skew. Distributions that lean heavily right or left. Suggests log-transform or different model assumptions.

Outliers. Points way off the main cloud. Maybe data errors, maybe genuinely interesting cases.

Separable classes. Class boundaries visible in the off-diagonal scatters. Tells you whether a simple linear model could work or you need something nonlinear.

Multicollinearity. Pairs of features that are highly correlated (off-diagonal scatter looks like a tight line). Often you can drop one or use regularisation.

Missing data patterns. Empty regions in scatter plots. Columns that appear all-zero or all-NaN.

Size considerations — pairplot doesn't scale to large datasets. With more than ~20 columns, the grid becomes unreadable. With more than ~50k rows, scatter plots become solid blobs (sample first). Both are easy to handle — pick the most-relevant 5-10 columns; subsample the rows.

For very small datasets, pair plots are trivially fast and give you the orientation you need. For larger datasets, the same chart with sampled data takes seconds and tells you almost as much.

After pair plot, the next charts I make depend on what pair plot revealed. If skew is everywhere, log-transform first. If multicollinearity is rampant, maybe PCA. If classes look completely separable, a linear model is probably enough.

One chart, two seconds, more orientation than reading the data dictionary. Worth the runtime.
#NumPy#Pandas#DataScience#Python#100DaysOfCode#EDA
POST 3 of 5 AfternoonAI/MLCode

Three plots, one matplotlib pattern

The fig/axes pattern is matplotlib's idiomatic API. Once you've seen it, every plotting library makes more sense — they all (eventually) call into something like this.

fig, axes = plt.subplots(rows, cols, figsize=(width, height))

Returns a Figure (the whole canvas) and an array of Axes (each individual subplot). You then plot on each axes by calling its methods — axes[0].hist(), axes[1].scatter(), axes[2].plot().

Look at the snippet — three subplots in a 1x3 grid.

axes[0].hist(df['age'], bins=30) — histogram of ages with 30 bins.

axes[1].scatter(df['x'], df['y'], alpha=0.4) — scatter of x vs y. alpha=0.4 makes points partially transparent so overlapping points show density.

axes[2].plot(df['date'], df['value']) — line chart over time.

Each ax has its own title, axis labels, ticks, legend — set independently. axes[i].set_title('...'), axes[i].set(xlabel='...', ylabel='...'), axes[i].legend().

fig.tight_layout() before plt.show() — adjusts spacing to prevent overlap. Always do this for multi-subplot figures.

Saving — fig.savefig('out.png', dpi=150, bbox_inches='tight'). dpi controls resolution; 150 is fine for slides, 300 for print. bbox_inches='tight' trims whitespace.

For production publish-quality plots, you'll add — explicit colors, custom fonts, axis limits, annotations, legends with locations. matplotlib gives you full control over each. The cost is verbosity; the benefit is exactness.

For a Jupyter notebook quick-look, df.plot() in pandas (which uses matplotlib under the hood) is enough. For final figures, drop into matplotlib direct.

Know the fig/ax pattern. Most plotting code you'll read uses it.
#NumPy#Pandas#DataScience#Python#100DaysOfCode#Matplotlib
POST 4 of 5 EveningAI/MLTip

If you're plotting more than 100k points, sample first

Plotting a million data points in a scatter plot is slow AND useless. Slow because the plot library has to render a million markers. Useless because the markers overlap into a solid blob — you can't see structure.

The fixes, in order of preference:

Sample. df.sample(50_000) gives you a random subset. For most exploratory plots, 50k points show the same patterns as the full data — outliers, clusters, trends are all visible.

Hexbin plot. plt.hexbin(x, y) divides the plane into hexagonal bins and colors each by the count of points in it. Great for showing 2D density. Doesn't suffer from overplotting.

2D histogram. plt.hist2d(x, y, bins=50) — same idea as hexbin but rectangular bins. Slightly faster; less aesthetically pleasing.

Datashader / vaex for very large datasets. Renders billion-point scatter plots by aggregating into image pixels. Used in genomics, geographic data, telemetry visualisations.

KDE. seaborn.kdeplot for smooth density estimates. Slower than hexbin, prettier output.

When alpha helps and when it doesn't:

On small N (< 10k), alpha=0.05 to 0.3 lets you see density through transparency. The piling up of partially transparent dots reveals where the points are concentrated.

On large N (> 100k), alpha doesn't help — even at alpha=0.01, a million dots saturate the canvas. Switch to hexbin or 2D histogram.

My first-draft scatter plot rule — if df has more than 100k rows, sample to 50k for visualisation. After looking at the sample, decide if I need a density-aware visualisation for the full data.

Fast plots are useful plots. Decorate later, after the analysis decisions are made.
#NumPy#Pandas#DataScience#Python#100DaysOfCode#DataViz
POST 5 of 5 NightAI/MLRecap

Day 33 — plot to think, not to publish

End of Day 33. Plotting done.

What we covered.

Morning, the plotting library landscape. matplotlib as the engine; seaborn, pandas .plot(), plotnine, plotly, bokeh, altair as layers and alternatives. Pick by job — sanity checks vs statistical vs polished vs interactive.

Midday, the pair plot as the orientation chart. sns.pairplot shows distributions and pairwise scatter. Reveals skew, outliers, separable classes, multicollinearity in seconds. The first chart I make on every new dataset.

Afternoon, the matplotlib fig/axes pattern. plt.subplots(rows, cols) returns a Figure and an array of Axes. Plot on each axes individually. fig.tight_layout() before show. The pattern underlies most plotting code you'll read.

Evening, the perf and readability rule for big data — sample first, decorate later. 50k points is enough for most exploratory plots. For density visualisation on large data, use hexbin or 2D histograms.

A broader theme — plots are a thinking tool, not a publication. Make many quick plots during analysis; polish a few for the final report. The first plot you make rarely answers the question; the conversation between you and the data is what produces insight.

Tomorrow, Day 34, EDA workflow. The seven questions I ask of every dataset before opening a model. The 'data understanding' phase that separates ML projects that succeed from ones that fail.

See you in the morning.
#NumPy#Pandas#DataScience#Python#100DaysOfCode#EDA