from plotnine import (
ggplot,
aes,
geom_line,
facet_wrap,
labs,
scale_x_datetime,
element_text,
theme_538
)from plotnine.data import meat
Line Plot
line plot
facet
theme
geom_line()
connects the dots, and is useful for time series data.
meat.head()
date | beef | veal | pork | lamb_and_mutton | broilers | other_chicken | turkey | |
---|---|---|---|---|---|---|---|---|
0 | 1944-01-01 | 751.0 | 85.0 | 1280.0 | 89.0 | NaN | NaN | NaN |
1 | 1944-02-01 | 713.0 | 77.0 | 1169.0 | 72.0 | NaN | NaN | NaN |
2 | 1944-03-01 | 741.0 | 90.0 | 1128.0 | 75.0 | NaN | NaN | NaN |
3 | 1944-04-01 | 650.0 | 89.0 | 978.0 | 66.0 | NaN | NaN | NaN |
4 | 1944-05-01 | 681.0 | 106.0 | 1029.0 | 78.0 | NaN | NaN | NaN |
Make it tidy.
= meat.melt(
meat_long ="date",
id_vars=["beef", "veal", "pork", "lamb_and_mutton", "broilers", "turkey"],
value_vars="animal",
var_name="weight"
value_name
).dropna()
meat_long.head()
date | animal | weight | |
---|---|---|---|
0 | 1944-01-01 | beef | 751.0 |
1 | 1944-02-01 | beef | 713.0 |
2 | 1944-03-01 | beef | 741.0 |
3 | 1944-04-01 | beef | 650.0 |
4 | 1944-05-01 | beef | 681.0 |
First try
= (
p ="date", y="weight"))
ggplot(meat_long, aes(x+ geom_line()
) p
It looks crowded because each there is more than one monthly entry at each x-point. We can get a single trend line by getting a monthly aggregate of the weights.
= meat_long.groupby("date").agg({"weight": "sum"}).reset_index()
meat_long_monthly_agg meat_long_monthly_agg
date | weight | |
---|---|---|
0 | 1944-01-01 | 2205.0 |
1 | 1944-02-01 | 2031.0 |
2 | 1944-03-01 | 2034.0 |
3 | 1944-04-01 | 1783.0 |
4 | 1944-05-01 | 1894.0 |
... | ... | ... |
955 | 2023-08-01 | 9319.1 |
956 | 2023-09-01 | 8586.1 |
957 | 2023-10-01 | 9452.5 |
958 | 2023-11-01 | 8951.1 |
959 | 2023-12-01 | 8555.1 |
960 rows × 2 columns
A Single Trend Line
(="date", y="weight"))
ggplot(meat_long_monthly_agg, aes(x+ geom_line()
)
Add some style
(="date", y="weight"))
ggplot(meat_long_monthly_agg, aes(x+ geom_line()
# Styling
+ scale_x_datetime(date_breaks="10 years", date_labels="%Y")
+ theme_538()
)
/home/runner/work/plotnine.org/plotnine.org/.venv/lib/python3.12/site-packages/mizani/breaks.py:448: FutureWarning: Passing the width as the parameter has been deprecated and will not work in a future version. Use breaks_date(width="4 years")
Or we can group by the animals to get a trend line for each animal
Multiple Trend Lines
(="date", y="weight", group="animal"))
ggplot(meat_long, aes(x+ geom_line()
# Styling
+ scale_x_datetime(date_breaks="10 years", date_labels="%Y")
+ theme_538()
)
/home/runner/work/plotnine.org/plotnine.org/.venv/lib/python3.12/site-packages/mizani/breaks.py:448: FutureWarning: Passing the width as the parameter has been deprecated and will not work in a future version. Use breaks_date(width="4 years")
Make each group be a different color.
(="date", y="weight", color="animal"))
ggplot(meat_long, aes(x+ geom_line()
# Styling
+ scale_x_datetime(date_breaks="10 years", date_labels="%Y")
+ theme_538()
)
/home/runner/work/plotnine.org/plotnine.org/.venv/lib/python3.12/site-packages/mizani/breaks.py:448: FutureWarning: Passing the width as the parameter has been deprecated and will not work in a future version. Use breaks_date(width="4 years")
A Trend Line Per Facet
Plot each group on a separate panel. The legend is no longer required and we adjust to the smaller panels by reducing the size
of the line, size
of the text and the number of grid lines.
def titled(strip_title):
return " ".join(s.title() if s != "and" else s for s in strip_title.split("_"))
("date", "weight", color="animal"))
ggplot(meat_long, aes(+ geom_line(size=.5, show_legend=False)
+ facet_wrap("animal", labeller=titled)
+ scale_x_datetime(date_breaks="20 years", date_labels="%Y")
+ labs(
="Date",
x="Weight (million pounds)",
y="Meat Production"
title
)+ theme_538(base_size=9)
)
/home/runner/work/plotnine.org/plotnine.org/.venv/lib/python3.12/site-packages/mizani/breaks.py:448: FutureWarning: Passing the width as the parameter has been deprecated and will not work in a future version. Use breaks_date(width="4 years")