Send a data frame through any function, without breaking the method chain.
pipe is the escape hatch that keeps chains intact. Pandas methods chain naturally because each returns a data frame — but the moment you need a function that isn't a Pandas method, the chain stops dead and you are back to temporary variables. pipe fixes that by handing your frame to any function you like and carrying on.
The clearest case is plotting, and it is where most people first meet the problem.
Official documentation: DataFrame.pipe
The problem it solves
Plotly Express takes the data frame as its first argument: px.line(df, x=..., y=...). That reads fine on its own, but it cannot be chained — there is no .px_line() method to call. So a chain that ends in a chart has to stop:
monthly = (
df
.set_index('time')
.resample('ME')
.agg(quakes=('mag', 'size'))
)
px.line(monthly) # chain broken; a variable exists only to be used once
pipe passes the frame along as the first argument, so the chart becomes one more step:
(
df
.set_index('time')
.resample('ME')
.agg(quakes=('mag', 'size'))
.pipe(px.line)
)
No monthly, no interruption. The chain reads top to bottom, ending in a picture.
The forms worth knowing
# The frame goes in as the first argument
df.pipe(px.line)
# Extra arguments pass straight through
df.pipe(px.bar, x='year', y='quakes', title='Earthquakes by month')
df.pipe(px.scatter, x='LON', y='LAT', color='WMO_WIND')
# Your own functions work the same way
df.pipe(clean_column_names)
df.pipe(add_per_capita, population=pop_df)
Two cases need more than the plain form.
When the frame is not the first parameter, name the parameter it should go to by passing a (function, 'argname') tuple:
df.pipe((some_function, 'data'), title='Chart')
When you need to reshape on the way in, use a lambda — this comes up with Series, where the plotting function wants values and labels separately:
series.pipe(lambda s_: px.pie(values=s_.values, names=s_.index))
That is the only reason to reach for a lambda here. If the frame goes in as the first argument, .pipe(px.line) says the same thing with less noise than .pipe(lambda df_: px.line(df_)).
A worked example, on real data
The USGS publishes every earthquake it records as CSV, through a public API with no key — the source Bamboo Weekly #3 worked with.
Load, bucket by month, aggregate, and plot — one expression:
import pandas as pd
from plotly import express as px
url = ('https://earthquake.usgs.gov/fdsnws/event/1/query.csv'
'?starttime=2024-01-01&endtime=2024-12-31&minmagnitude=6')
(
pd.read_csv(url, usecols=['time', 'mag'], parse_dates=['time'])
.set_index('time')
.resample('ME')
.agg(quakes=('mag', 'size'),
strongest=('mag', 'max'))
.pipe(px.line)
)
That returns a Plotly figure with two traces — quakes and strongest — one point per month across 2024. Five steps, no intermediate names, and the whole analysis is readable as a single thought.
Add arguments when the defaults are not what you want:
(
pd.read_csv(url, usecols=['time', 'mag'], parse_dates=['time'])
.set_index('time')
.resample('ME')
.agg(quakes=('mag', 'size'))
.reset_index()
.pipe(px.bar, x='time', y='quakes',
title='Magnitude 6+ earthquakes, 2024')
)
Three mistakes people make
Wrapping in a lambda when you do not need one. .pipe(lambda df_: px.line(df_)) and .pipe(px.line) do exactly the same thing, because pipe already passes the frame as the first argument. Save the lambda for when the frame has to go somewhere else.
Calling the function instead of naming it. df.pipe(px.line(df)) calls px.line yourself and then hands the result to pipe. Pass the function itself — df.pipe(px.line) — and let pipe do the calling.
Forgetting that pipe returns whatever the function returns. It is not obliged to give you a data frame back. .pipe(px.line) returns a Plotly figure, .pipe(len) returns an integer. That is the point — but it does mean a pipe step is usually the last one in the chain unless your function returns a frame.
Watch it
What the Pandas "pipe" method does covers this directly. For the wider style pipe completes, see Optimizing Pandas queries with method chaining and Method chaining in Pandas: Cleaner queries with assign, loc, and lambda.
Practice it
Work through a pipe exercise, with instant feedback and no signup required: practice.lernerpython.com/bamboo-weekly/pipe/
Go deeper
Bamboo Weekly is the practice. If you want the structured version — full courses with downloadable Jupyter notebooks, plus live Pandas office hours when you get stuck — that is LernerPython+Data. A paid Bamboo Weekly subscription is included with it.
See it on real data
Below are the 60 Bamboo Weekly exercises that use pipe on real-world data — try each one, then study the worked solution.
- Bamboo Weekly #182: Surveillance technology
- Bamboo Weekly #181: Housing costs
- Bamboo Weekly #180: Movies
- Bamboo Weekly #179: Krakow tourism
- Bamboo Weekly #178: Harmful algal bloom
- Bamboo Weekly #177: European Summer
- Bamboo Weekly #176: Religious restrictions
- Bamboo Weekly #175: Inflation
- Bamboo Weekly #174: Vacation
- Bamboo Weekly #173: IPOs
- Bamboo Weekly #172: World Cup
- Bamboo Weekly #171: Hantavirus
- Bamboo Weekly #170: Port of Long Beach
- Bamboo Weekly #169: Press freedom
- Bamboo Weekly #168: US gas prices
- Bamboo Weekly #167: Oil prices
- Bamboo Weekly #165: Artemis II
- Bamboo Weekly #164: Fertilizer
- Bamboo Weekly #163: Daylight saving time
- Bamboo Weekly #162: Spotify and car accidents
- Bamboo Weekly #161: Missiles in Israel
- Bamboo Weekly #160: Strait of Hormuz
- Bamboo Weekly #159: State of the Union
- Bamboo Weekly #158: University endowments
- Bamboo Weekly #157: Government corruption
- Bamboo Weekly #156: Winter Olympics
- Bamboo Weekly #155: Gold
- Bamboo Weekly #153: Venezuela
- Bamboo Weekly #152: Congestion pricing
- Bamboo Weekly #151: PyPI in 2025
- Bamboo Weekly #150: Kalshi
- Bamboo Weekly #149: Flu season
- Bamboo Weekly #148: US Manufacturing
- Bamboo Weekly #147: Presidential pardons
- Bamboo Weekly #145: Economic indicators
- Bamboo Weekly #144: Museum Heists
- Bamboo Weekly #143: Phones in school
- Bamboo Weekly #142: Hurricanes
- Bamboo Weekly #141: Argentina
- Bamboo Weekly #139: Chinese exports
- Bamboo Weekly #138: Federal workers
- Bamboo Weekly #137: UN Security Council
- Bamboo Weekly #136: Indian vehicles
- Bamboo Weekly #134: Taiwan weather
- Bamboo Weekly #133: Wind power
- Bamboo Weekly #132: JetBrains survey
- Bamboo Weekly #130: Jobs reporting
- Bamboo Weekly #126: EV sales
- Bamboo Weekly #123: Missiles
- Bamboo Weekly #109: Cacao nibs
- Bamboo Weekly #99: Literacy and numeracy
- Bamboo Weekly #98: Retail sales
- Bamboo Weekly #97: Drones
- Bamboo Weekly #92: Climate disaster costs
- Bamboo Weekly #91: Roller coasters
- Bamboo Weekly #83: Gasoline prices
- Bamboo Weekly #75: Refugees
- Bamboo Weekly #70: Moon missions
- Bamboo Weekly #67: Electric cars
- Bamboo Weekly #44: Global economics
Part of the Pandas Methods Index. See also practice by skill.