Plotting from pandas
df.plot() is a shortcut into matplotlib, not an alternative to it
df.plotax=kind=df.plot.barsubplots=Truegroupby().plotWatch it happen
Play it through, or step back and forth yourself.
week.plot()every numeric column vs the index# labels from the column nameslegend for free# x label from the index name"day"week.plot(y="delhi")just oneweek.plot(). pandas draws every numeric column against the index, names the series from the column names, labels the x axis from the index name, and builds the legend. For looking at data, nothing beats it.
The idea
pandas has a .plot() that draws with matplotlib underneath, and it gets you to a chart in one line:
week.plot()Every numeric column against the index, series named from the column names, x label from the index name, legend built. For looking at data — which is most of what you do — nothing beats it.
It returns an Axes
This is the part worth internalising:
ax = week.plot()
type(ax).__name__ # 'Axes' — a normal matplotlib Axes
ax.set_title("Delhi runs ahead all week", loc="left")
ax.annotate(...)
ax.set_yscale("log")Everything in this track still applies. df.plot() is a shortcut into matplotlib, not a separate plotting library — which means you never have to choose between them, and you never have to abandon a pandas chart because it needs one thing pandas doesn't expose.
ax= is the hinge
fig, axd = plt.subplot_mosaic(
[["trend", "trend"],
["items", "wait"]],
layout="constrained",
)
week.plot(ax=axd["trend"]) # pandas
axd["items"].barh(items, sold) # matplotlib
axd["wait"].hist(orders["wait"], bins=12)Pass ax= and pandas draws into your Axes instead of creating its own Figure. Without it, pandas makes a fresh figure and your careful layout sits there empty — which is the single most common confusion when people first mix the two.
The kinds
df.plot(kind="bar") df.plot.bar()
df.plot(kind="barh") df.plot.barh()
df.plot(kind="hist") df.plot.hist(bins=20)
df.plot(kind="box") df.plot.box()
df.plot(kind="area") df.plot.area()
df.plot(kind="kde") df.plot.kde()
df.plot.scatter(x="temp", y="cups") # scatter needs both namesThe accessor form (df.plot.bar()) is the same thing with autocompletion and a docstring per kind, which is worth having. Also useful:
week.plot(subplots=True) # one panel per column
week.plot(y="delhi") # just one column
week.plot(secondary_y="mumbai") # a twin axis — see lesson 10 firstShape the data first
pandas plots the frame it is given, so the reshaping is the plotting. This is where the pandas track pays off:
orders.groupby("item")["cups"].mean().sort_values().plot.barh()
orders.set_index("when")["cups"].resample("D").sum().plot()
orders.pivot_table(index="item", values="wait", aggfunc="median").plot.barh()Each of those is a whole chart in one expression, and the chart is legible because the frame was already in the shape of the chart. When a pandas plot looks wrong, the frame is usually the wrong shape — check that before you reach for plotting arguments.
Where the line is
Use df.plot() when:
- you're exploring and want to see the shape of something;
- the chart is simple and will stay simple;
- it's one panel of a layout — with
ax=.
Drop to matplotlib when:
- you need a layout, a twin axis, an inset, or annotations;
- you're building a figure that will be published or presented;
- you want the same chart for twenty groups — write a function (next lesson).
In practice the split is: make the Figure and Axes with matplotlib, fill them with pandas. You get one line per chart and full control of the page.
Two things that surprise people
df.plot(kind="bar") treats the index as categories, not positions — so a date index gives you one bar per date with every date printed underneath. For time series, use the line kind, or resample first.
And pandas sets labels from column and index names, which means df.rename(columns=...) before plotting is often the fastest way to fix a legend.
See it run
The lesson's code, ready to run and to fiddle with.
Putting the kettle on…
Starting up…
Worked example
not gradedAlready written and ready to go — press Run to see what it does, then change a number, a column name, anything, and run it again.
trydropping ax= from one of the calls and seeing that panel stay empty.
Your turn
3 exercises. Write the code yourself, then press Check — a nudge and the answer are there if you want them.
Draw week into an Axes you made yourself, then return the labels pandas gave the lines and the x label it took from the index: [[l.get_label() for l in ax.lines], ax.get_xlabel()].
Make a 1×2 grid and draw week into the left panel only. Return [len(axes[0].lines), len(axes[1].lines)] — proof that ax= put it where you asked.
The reshaping is the chart. Return mean cups per item, sorted ascending and rounded to 1 decimal place, as a dict — the exact thing you'd hand to .plot.barh().
