Polars is a blazing-fast DataFrame library, but unlike pandas it does not ship with a built-in .plot() method. That is a deliberate design choice — Polars focuses on data manipulation, and leaves visualisation to dedicated libraries like matplotlib, plotly, or altair.
The good news: connecting Polars to matplotlib is straightforward. You extract a column as a Python list or NumPy array, then pass it to any matplotlib function. This article walks through the full workflow using a dataset of EV vs Diesel car registrations:
- Create a Polars DataFrame with long-form data
- Pivot the data to wide form for easy plotting
- Draw a simple single-series line chart
- Plot two series on the same axes
- Polish the chart with labels, legend, grid, and title
The dataset
We will use a dataset tracking monthly new-car registrations (in thousands) for electric vehicles (EV) and diesel cars across a single calendar year. The EV column trends upward as adoption accelerates, while diesel registrations decline — a pattern seen in many markets worldwide.
The data is in long form: each row is one vehicle type in one month. This is great for filtering and aggregation, but for plotting we usually want wide form — one column per series. Polars makes this easy with .pivot().
Pivot to wide form
The .pivot() method reshapes the DataFrame so that each unique value in the on column becomes its own column. We keep month as the index (row identifier) and spread monthly_registrations across the vehicle types:
Now we have a clean 12-row DataFrame with columns month, EV, and Diesel. Each column can be extracted directly and passed to matplotlib.
A simple line plot
To plot a Polars column with matplotlib, convert it to a list using .to_list() (or a NumPy array using .to_numpy()). Here is the simplest possible line chart — just the EV registrations over the year:
Three things to note:
- We call
plt.subplots()to get aFigureandAxesobject — this is the recommended matplotlib pattern. - We use
.to_list()to convert Polars Series to plain Python lists that matplotlib understands. - The last line returns
figso the interactive environment renders it as an image.
Plotting two series
Adding a second series is as simple as calling ax.plot() again on the same axes. Let's overlay the diesel registrations alongside the EV data:
The crossover point — where EV registrations surpass diesel — is immediately visible. We added label= to each ax.plot() call and then ax.legend() to display the legend. The chart works, but it could use some polish.
A polished chart
Let's add axis labels, a title, grid lines, custom y-axis limits, and a tighter layout to produce a publication-ready chart:
Key additions:
figsize=(9, 5)— a wider figure to avoid cramped month labels.marker='o'andmarker='s'— circle and square markers to distinguish the series even without colour.ax.set_ylim(0, 16)— anchors the y-axis at zero so the visual difference is honest.ax.grid(True, alpha=0.3)— light grid lines for easier reading.fig.tight_layout()— prevents labels from being clipped.
Try editing the code blocks above — change marker styles, swap colours, adjust figsize, or plot a bar chart with ax.bar() instead of ax.plot().
Polars vs pandas: plotting compared
If you are coming from pandas, here is how the plotting workflow differs:
df.plot()→ Not available in Polars. Use matplotlib (or plotly/altair) directly.df['col'].values→df['col'].to_list()ordf['col'].to_numpy()df.pivot_table()→df.pivot(on=..., index=..., values=...)- No
reset_index()needed — Polars pivot always returns a flat DataFrame.
The extra step of extracting columns with .to_list() is minimal, and you gain full control over the matplotlib API rather than relying on pandas' convenience wrapper.
References
- Polars documentation: polars.DataFrame.pivot
- Polars documentation: polars.Series.to_list
- Matplotlib documentation: Axes.plot
- Matplotlib documentation: pyplot.subplots
- Related tutorial: How to Create a Graph in Python with matplotlib