Menu

Tutorial10 min read

How to Plot Time Series Data in Python: matplotlib, pandas, and plotly

By Francesco VillasmuntaUpdated March 21, 2026
How to Plot Time Series Data in Python: matplotlib, pandas, and plotly

Time series data—sensor readings, climate measurements, stock prices, patient vitals—needs special handling in matplotlib because the x-axis carries dates rather than plain numbers. Matplotlib understands Python datetime objects and pandas DatetimeIndex natively, but formatting the axis cleanly requires a few extra lines.

Date formatting

mdates.DateFormatter controls tick labels. fig.autofmt_xdate() rotates them automatically.

Rolling average

Overlay a rolling mean to show the trend without hiding the raw signal. Keep both lines on the same axis.

Dual axes

Use ax.twinx() only when two variables share the same time axis but have incompatible scales or units.

1. Basic time series plot

Plot the series with ax.plot(dates, values). Apply mdates.MonthLocator to place one tick per month and DateFormatter to control the label text.

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

dates = pd.date_range("2024-01-01", periods=90, freq="D")
values = pd.Series(range(90), index=dates) + pd.Series(
    [i * 0.3 for i in range(90)], index=dates
)

fig, ax = plt.subplots(figsize=(9, 4))
ax.plot(dates, values, lw=1.5, color="#6b21a8")
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter("%b %Y"))
fig.autofmt_xdate()
ax.set_ylabel("Measurement")
ax.set_title("Daily Time Series")
plt.tight_layout()

2. Rolling averages

Use Series.rolling(window).mean() from pandas. Plot the raw signal at low alpha and the rolling means at full opacity so the trend is readable.

Try it

Try it now: plot your own time series

Upload temporal data and generate a clean time-series figure with trend smoothing and readable date formatting.

Generate my time-series chart

Newsletter

Get a weekly Python plotting tip

One concise tip each week for cleaner, faster scientific figures. Built for researchers who publish.

No spam. Unsubscribe anytime.
import pandas as pd
import matplotlib.pyplot as plt

dates = pd.date_range("2024-01-01", periods=180, freq="D")
rng = pd.Series(range(180), index=dates).add(
    pd.Series([i ** 0.5 for i in range(180)], index=dates) * 0.5
)

rolling_7  = rng.rolling(7).mean()
rolling_30 = rng.rolling(30).mean()

fig, ax = plt.subplots(figsize=(9, 4))
ax.plot(dates, rng, alpha=0.25, color="#6b21a8", lw=1, label="Raw")
ax.plot(dates, rolling_7,  color="#f59e0b", lw=1.5, label="7-day mean")
ax.plot(dates, rolling_30, color="#10b981", lw=2,   label="30-day mean")
ax.legend(frameon=False)
ax.set_ylabel("Measurement")
fig.autofmt_xdate()
plt.tight_layout()

3. Dual y-axis (two variables, shared x)

Use a second axis sparingly — only when two datasets share a meaningful time relationship but have incompatible units. Colour-code both the lines and the axis labels to make the mapping unambiguous.

import pandas as pd
import matplotlib.pyplot as plt

dates  = pd.date_range("2024-01-01", periods=60, freq="D")
temp   = pd.Series([20 + i * 0.3 for i in range(60)], index=dates)
precip = pd.Series([5  - i * 0.05 for i in range(60)], index=dates)

fig, ax1 = plt.subplots(figsize=(9, 4))
ax2 = ax1.twinx()

ax1.plot(dates, temp,   color="#6b21a8", lw=2, label="Temperature (°C)")
ax2.bar(dates,  precip, color="#f59e0b", alpha=0.4, width=0.8, label="Precipitation (mm)")

ax1.set_ylabel("Temperature (°C)", color="#6b21a8")
ax2.set_ylabel("Precipitation (mm)", color="#f59e0b")
fig.autofmt_xdate()
plt.tight_layout()

Date tick locator reference

LocatorUse when
HourLocatorData spans hours or a single day
DayLocatorData spans days to a few weeks
WeekdayLocatorWeekly business data
MonthLocatorData spans months to a few years
YearLocatorData spans many years or decades
AutoDateLocatorLet matplotlib choose automatically (default)

Common mistakes

  • Overlapping tick labels — call fig.autofmt_xdate() or rotate manually with plt.xticks(rotation=45).
  • Plotting integers instead of dates — ensure your x-axis is a DatetimeIndex or datetimearray, not a string column.
  • Hiding raw data with only a smoothed line— show the underlying signal at low opacity alongside the rolling average.
  • Dual axes without colour coding — readers cannot tell which line belongs to which axis without clear colour cues.

Upload a CSV with a date column and describe the time series plot you need — Plotivy generates the code with correct date formatting, rolling averages, and publication-ready styling.

Plot your time series in Plotivy
Tags:#time series#matplotlib#pandas#python#dates

Related chart guides

Apply this tutorial directly in the chart gallery with ready-to-run prompts and examples.

Found this helpful? Share it with your network.

FV
Francesco Villasmunta

Experimental Physicist & Photonics Researcher

Hands-on experience in silicon photonics, semiconductor fabrication (DRIE/ICP-RIE), optical simulation, and data-driven analysis. Built Plotivy to help researchers focus on discoveries instead of data struggles.

More about the author

Visualize your own data

Apply the techniques from this article to your own datasets. Upload CSV, Excel, or paste data directly.

Start Analyzing - Free