← Matplotlib·Lesson 17·12 min·0/3 exercises

Plotting from pandas

df.plot() is a shortcut into matplotlib, not an alternative to it

df.plotax=kind=df.plot.barsubplots=Truegroupby().plot

Watch it happen

Play it through, or step back and forth yourself.

daydelhimumbai
Mon4230
Tue5836
Wed5144
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 one

week.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.

Hand-drawn notes showing that a pandas plot call returns an Axes and accepts one, which is what lets pandas speed and matplotlib control be used together.

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 names

The 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 first

Shape 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.

Hand-drawn notes showing that a pandas plot uses the index as x and draws one line per column, so the data must be reshaped wide before plotting.

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.

Practice

Write it yourself. The answer is there when you want it.

Putting the kettle on…

Starting up…

Write it yourself

not graded

Lay out three named panels with subplot_mosaic, then let pandas fill them — every .plot call takes ax=. Daily cups as a line, mean cups per item as sorted horizontal bars, and the wait times as a histogram, each titled from the left. Print what one of those .plot calls actually returns, and the by-item numbers rounded. Finish with fig.

Write something and press Run — the output appears here.

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()].

your answer

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.

your answer

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().

your answer