How to Draw a Candlestick Chart in R – Using ggplot2 and plotly

·

Candlestick charts are a cornerstone of financial data visualization, widely used by traders and analysts to interpret price movements of assets such as stocks, cryptocurrencies, and commodities. Each candlestick encapsulates four critical data points within a defined time interval—opening price, closing price, highest price, and lowest price—offering a concise yet powerful snapshot of market dynamics.

The body of the candlestick reflects the range between the opening and closing prices. When the closing price exceeds the opening price, the candle is typically displayed in green or left unfilled, signaling bullish momentum. Conversely, a red or filled candle indicates that the closing price was lower than the opening, reflecting bearish sentiment. Thin lines extending above and below the body, known as wicks or shadows, reveal the full extent of price fluctuation during the period.

These visual cues allow market participants to identify patterns—such as dojis, hammers, and engulfing formations—that may signal potential trend reversals or continuations. As such, mastering candlestick charting is essential for technical analysis and informed trading decisions.

In this guide, you'll learn how to create professional candlestick charts in R using two powerful tools: ggplot2 for static visualizations and plotly for interactive exploration. We’ll walk through data retrieval, chart construction, customization, and best practices—all within the R environment.


Key Tools and Libraries

To build candlestick charts in R, we’ll leverage the following packages:

First, load the required libraries:

library(ggplot2)
library(tidyquant)
library(quantmod)
library(plotly)

Retrieving Financial Data

We'll use Apple Inc. (AAPL) as our example asset. The getSymbols() function from quantmod fetches historical stock data directly from Yahoo Finance.

getSymbols("AAPL", src = "yahoo")

Next, convert the time-series object into a tidy data frame and select the most recent 30 trading days for clarity:

df <- data.frame(Date = index(AAPL), coredata(AAPL)) |> tail(30)

This creates a clean dataset with columns including AAPL.Open, AAPL.High, AAPL.Low, AAPL.Close, and others—perfect for plotting.


Creating a Candlestick Chart with ggplot2

Using tidyquant’s geom_candlestick(), we can easily integrate candlesticks into the ggplot2 framework:

df |> 
  ggplot(aes(x = Date)) +
  geom_candlestick(
    aes(open = AAPL.Open, high = AAPL.High, low = AAPL.Low, close = AAPL.Close),
    colour_up = "darkgreen", 
    fill_up = "darkgreen"
  ) +
  coord_x_date(
    xlim = range(df$Date),
    ylim = c(min(df$AAPL.Low) - 10, max(df$AAPL.High) + 10)
  ) +
  labs(
    title = paste("Apple Inc. (AAPL) Stock Prices Between", min(df$Date), "and", max(df$Date)),
    x = "Date",
    y = "Price (USD)"
  ) +
  theme_minimal()

👉 Discover how real-time data enhances trading strategies

This code generates a polished static candlestick chart. Note that we’ve customized upward candles in dark green. You can further adjust colors using colour_down and fill_down for bearish periods.

Pro Tip: If you encounter warnings about dropped aesthetics, ensure your date column is properly recognized as Date class and that each row represents a unique time point—no duplicate dates.

You can export this chart using ggsave() or embed it in reports via R Markdown.


Building an Interactive Chart with plotly

For dynamic exploration, plotly transforms static plots into interactive dashboards. Here's how to create an interactive candlestick chart:

fig <- df %>%
  plot_ly(
    x = ~Date,
    type = "candlestick",
    open = ~AAPL.Open,
    high = ~AAPL.High,
    low = ~AAPL.Low,
    close = ~AAPL.Close
  ) %>%
  layout(
    title = paste("Apple Inc. (AAPL) Stock Prices Between", min(df$Date), "and", max(df$Date)),
    xaxis = list(title = "Date"),
    yaxis = list(title = "Price (USD)")
  )

fig

The resulting chart allows users to:

This interactivity is invaluable for deep-dive analysis and presentations.

👉 Explore advanced charting tools for deeper market insights


Core Keywords for SEO

To align with search intent and improve discoverability, key terms naturally integrated throughout this article include:

These keywords reflect common queries from data scientists, financial analysts, and R learners seeking practical guidance on market visualization.


Frequently Asked Questions

Q: Can I change the color of downward candles in ggplot2?
A: Yes. Use the colour_down and fill_down arguments in geom_candlestick() to set custom colors for bearish candles (e.g., red or black).

Q: Why am I getting aesthetic warnings when using geom_candlestick()?
A: This usually happens if ggplot2 cannot infer proper grouping. Ensure your data has one observation per date and that the Date column is in Date format. Sorting by date may also help.

Q: How do I update the data to include today’s prices?
A: Simply rerun getSymbols("AAPL", src = "yahoo") before creating the dataframe. The function pulls the latest available data from Yahoo Finance.

Q: Can I add volume bars below the candlestick chart?
A: Yes. In ggplot2, you can use facet_grid() or patchwork to combine a volume bar chart beneath the candlestick plot. With plotly, overlaying subplots is supported via subplot().

Q: Is it possible to make the plotly chart responsive in a web app?
A: Absolutely. You can embed the plotly object in a Shiny app or HTML page where it automatically scales and responds to user interactions.

Q: Can I use this method for cryptocurrency data?
A: Yes. While Yahoo Finance supports some crypto pairs, you might also source crypto OHLC data via APIs like Binance or OKX. Once structured properly (with Open, High, Low, Close columns), the same plotting logic applies.

👉 Access real-time crypto data to power your R analyses


By combining the precision of ggplot2 with the interactivity of plotly, R becomes a formidable tool for financial visualization. Whether you're conducting backtesting, presenting findings, or monitoring live markets, mastering candlestick charts in R empowers deeper insights and better decision-making.