Plotting Market Data with Matplotlib
Use matplotlib to plot prices, indicators, equity curves, drawdowns and return histograms, with clear examples and tips for honest, readable trading charts.
Numbers alone hide a lot. An equity curve shows whether returns came steadily or from one lucky month; a drawdown chart shows how painful the losses were; a histogram reveals fat tails that a single average hides. matplotlib is Python's original and most widely used plotting library, and pandas plots use it underneath. You do not need beautiful charts for research, but you do need honest ones, and a handful of chart types covers almost everything a trader needs.
The charts traders need#
| Chart | Answers | Lesson |
|---|---|---|
| Price with indicators | What did the signal see? | Moving Averages Explained |
| Equity curve | How did the account grow? | Backtesting Methodology |
| Drawdown | How deep and long were losses? | Maximum Drawdown |
| Return histogram | How are returns distributed? | Fat Tails |
| Rolling metric | Is performance stable over time? | Rolling and Expanding Windows |
| Scatter | How do two assets or a signal and returns relate? | Covariance and Correlation |
Price and moving averages#
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(df.index, df["Close"], label="Close", linewidth=1)
ax.plot(df.index, df["Close"].rolling(50).mean(), label="50 day SMA")
ax.plot(df.index, df["Close"].rolling(200).mean(), label="200 day SMA")
ax.set_title("Price and moving averages")
ax.legend()
plt.show()
Equity curve and drawdown together#
equity = (1 + df["strategy"].fillna(0)).cumprod()
drawdown = equity / equity.cummax() - 1
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(10, 6),
gridspec_kw={"height_ratios": [3, 1]})
ax1.plot(equity, label="Strategy")
ax1.set_yscale("log")
ax2.fill_between(drawdown.index, drawdown, 0, alpha=0.4)
ax2.set_ylabel("Drawdown")
plt.show()
Sharing the x axis lines up each drawdown with the part of the equity curve that caused it.
Why use a log scale for equity#
On a normal scale, a move from $100 to $200 looks small next to a later move from $1,000 to $2,000, even though both doubled the account. A log scale shows equal percentage changes as equal heights, so early and late performance can be compared fairly. Use it for any equity curve or price chart spanning large changes. See Compounding and Geometric vs Arithmetic Returns.
Return histogram#
rets = df["strategy"].dropna()
fig, ax = plt.subplots()
ax.hist(rets, bins=60)
ax.axvline(rets.mean(), linestyle="--")
ax.set_title("Daily strategy returns")
plt.show()
Compare the shape with a normal distribution: trading returns usually have taller peaks and fatter tails. See Normal Distribution and Skewness and Kurtosis.
Candlestick charts#
matplotlib has no built in candlestick function. The mplfinance package adds one, and plotly offers interactive candlesticks that zoom in a browser. For live trading charts, dedicated charting platforms are far easier. See Charting Platforms Compared and How to Read Candlesticks.
Rules for honest charts#
- Label axes and units, including currency and whether returns are percentages.
- Use log scales for long equity curves.
- Show costs included or state that they are excluded.
- Do not crop the worst period out of the date range.
- Plot in and out of sample periods in different colours. See In-Sample vs Out-of-Sample Testing.
- Save charts with the code and data version that produced them. See Backtest Reproducibility.
Interactive charts#
matplotlib produces static images, which are ideal for reports and quick checks. When you want to zoom into a single day or hover to read exact values, plotly and bokeh create interactive charts that open in a browser or notebook. They are especially useful for inspecting individual trades on intraday data, where a static chart of a full year would squeeze thousands of bars into a few pixels. A practical workflow is to use matplotlib for the overview charts saved with each backtest and an interactive library for digging into specific periods, such as the worst drawdown or the trades with the largest slippage. See MAE and MFE for charts that show how far each trade moved for and against you.
Frequently asked questions#
What is matplotlib used for in trading?#
Plotting prices, indicators, equity curves, drawdowns, histograms and other charts for research and reporting.
How do I plot candlesticks in Python?#
Use the mplfinance package for static candlestick charts or plotly for interactive ones.
Should equity curves use a log scale?#
Usually yes, because a log scale shows equal percentage gains as equal heights, which makes long periods easier to compare.
Next, compare the main Python backtesting frameworks in Backtesting Libraries Compared.
3 quick questions on this lesson. Get them all right to finish it.
Turn on JavaScript to take the quiz.