How to Draw One Candlestick from OHLC Data in Python

 one candlestick from Open, High, Low, and Close data using Python and matplotlib

A candlestick can look like a special market symbol. But underneath, it is only a drawing made from four numbers: Open, High, Low, and Close.

In Phase 1, you already learned how those numbers live inside a pandas DataFrame. Now we will turn one row of that table into one candlestick.

We will build it ourselves with matplotlib. No candlestick library will draw it for us yet.

What you will finish: one real AAPL trading day will appear on your screen as a candlestick that you built from its OHLC values.

1. Start with the Four Numbers

A candlestick summarizes one time interval. In this lesson, one interval is one trading day.

Open
High
Low
Close

Read the words literally:

  • Open — where the price started.
  • High — the highest price reached during the day.
  • Low — the lowest price reached during the day.
  • Close — where the price ended.

A candlestick is simply a compact picture of those four values.

2. Why Build One Candle by Hand?

Python libraries can create complete candlestick charts automatically. We will use faster tools later when they become useful.

But first, we want to know what the chart is actually doing.

OHLC numbers
     ↓
one vertical line
     +
one thick body
     ↓
one candlestick

3. Create a New Python File

In your alphesta-lab folder, create:

one_candlestick.py

We will make the script use the folder that contains the Python file as its working folder. This keeps the code and its result together even if VS Code was opened from somewhere else.

from pathlib import Path
import os

SCRIPT_DIR = Path(__file__).resolve().parent
os.chdir(SCRIPT_DIR)

__file__ means the current Python file. .parent gives us the folder that contains it.

We will use two packages that are already part of your Alphesta lab.

import FinanceDataReader as fdr
import matplotlib.pyplot as plt

4. Download a Small AAPL Dataset

symbol = "AAPL"
start_date = "2025-01-02"
end_date = "2025-01-10"

df = fdr.DataReader(symbol, start_date, end_date)

Choose the first row:

row_number = 0
day = df.iloc[row_number]

5. Pull OHLC Out of That Row

open_price = float(day["Open"])
high_price = float(day["High"])
low_price = float(day["Low"])
close_price = float(day["Close"])

Print them before drawing anything. The terminal will show the selected numbers.

6. Decide Whether the Candle Is Up or Down

is_up_candle = close_price >= open_price
candle_color = "green" if is_up_candle else "red"

7. Turn Open and Close into a Body

body_bottom = min(open_price, close_price)
body_height = abs(close_price - open_price)

8. Draw the Wick from Low to High

ax.vlines(
    x=0,
    ymin=low_price,
    ymax=high_price,
    color=candle_color,
    linewidth=2,
)

9. Draw the Body from Open to Close

ax.bar(
    x=0,
    height=body_height,
    bottom=body_bottom,
    width=0.6,
    color=candle_color,
    edgecolor=candle_color,
)

10. Complete Code

from pathlib import Path
import os

import FinanceDataReader as fdr
import matplotlib.pyplot as plt

SCRIPT_DIR = Path(__file__).resolve().parent
os.chdir(SCRIPT_DIR)

print("Working folder:")
print(SCRIPT_DIR)
print()

symbol = "AAPL"
start_date = "2025-01-02"
end_date = "2025-01-10"

row_number = 0

df = fdr.DataReader(symbol, start_date, end_date)

day = df.iloc[row_number]
date_label = df.index[row_number].strftime("%Y-%m-%d")

open_price = float(day["Open"])
high_price = float(day["High"])
low_price = float(day["Low"])
close_price = float(day["Close"])

print("Selected market data:")
print("Date :", date_label)
print("Open :", open_price)
print("High :", high_price)
print("Low  :", low_price)
print("Close:", close_price)
print()

is_up_candle = close_price >= open_price
candle_color = "green" if is_up_candle else "red"

body_bottom = min(open_price, close_price)
body_height = abs(close_price - open_price)

fig, ax = plt.subplots(figsize=(5, 7))

ax.vlines(
    x=0,
    ymin=low_price,
    ymax=high_price,
    color=candle_color,
    linewidth=2,
)

ax.bar(
    x=0,
    height=body_height,
    bottom=body_bottom,
    width=0.6,
    color=candle_color,
    edgecolor=candle_color,
)

price_range = high_price - low_price
padding = price_range * 0.15 if price_range > 0 else 1

ax.set_xlim(-1, 1)
ax.set_ylim(low_price - padding, high_price + padding)
ax.set_xticks([0])
ax.set_xticklabels([date_label])
ax.set_ylabel("Price")
ax.set_title(f"{symbol} — One Candlestick")
ax.grid(axis="y", alpha=0.25)

plt.tight_layout()

output_file = SCRIPT_DIR / "one_candlestick.png"
plt.savefig(output_file, dpi=160, bbox_inches="tight")

print("Chart saved:")
print(output_file)
print()
print("A chart window will now open.")
print("Close the chart window when you are finished viewing it.")

plt.show()

11. Check Your Result

When you run the file, the terminal first prints the working folder. Then it prints the selected date and four OHLC values.

The script saves:

one_candlestick.png

in the same folder as one_candlestick.py. The terminal also prints the exact saved image path.

Finally, plt.show() opens the chart window so you can inspect the result immediately.

12. Change One Thing Yourself

Change:

row_number = 0

to:

row_number = 1

Run the file again and compare the new OHLC values with the new candle shape.

What You Just Learned

A candlestick is a visual summary of Open, High, Low, and Close during one interval. You now know how one real DataFrame row becomes one candle.

Where Do We Go Next?

Next, we will repeat this same drawing logic over several DataFrame rows and build a full candlestick chart from scratch.