Plotly Package

Data Visualization

Various Interactive Plots using Plotly Package

Yeongeun Jeon
11-07-2021
pacman::p_load("quantmod",
               "dplyr", "lubridate",
               "plotly", "ggplot2")

주식 불러오기

# 카카오
kakao <- getSymbols("035720.KS", auto.assign = FALSE,
                    # src='yahoo',
                    from = "2018-01-01", to = today())

colnames(kakao) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
kakao <- cbind(Date = index(kakao), data.frame(kakao))

# 삼성samsung <- getSymbols("005930.KS", auto.assign = FALSE,
                    from = "2018-01-01", to = today())

colnames(samsung) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
samsung <- cbind(Date = index(samsung), data.frame(samsung))

CandleStick


Version 1

inc <- list(line = list(color = 'red'))   # 상승할 때 색깔
dec <- list(line = list(color = 'blue'))  # 하락할 때 색깔
# Verson 1
kakao %>%
  plot_ly(x = ~Date, type="candlestick",
          open = ~Open, close = ~Close,
          high = ~High, low = ~Low,
          increasing = inc, decreasing = dec) %>%
  # add_lines(x = ~Date, y = ~Close, line = list(color = 'black', width = 0.75), inherit = F) %>%
  layout(title= "CandleStick Chart",
         yaxis = list(title = "Price",
                      tickformat = "digits"))

Version 2

kakao %>%
  plot_ly(x = ~Date, type="candlestick",
          open = ~Open, close = ~Close,
          high = ~High, low = ~Low,
          increasing = inc, decreasing = dec) %>%
  # add_lines(x = ~Date, y = ~Close, line = list(color = 'black', width = 0.75), inherit = F) %>%
  layout(title= "CandleStick Chart",
         xaxis = list(rangeslider = list(visible = F)), # Without Rangeslider
         yaxis = list(title = "Price",
                      tickformat = "digits"))

Version 3

cs1 <- kakao %>%
  plot_ly(x = ~Date, type="candlestick",
          open = ~Open, close = ~Close,
          high = ~High, low = ~Low,
          increasing = inc, decreasing = dec) %>%
  layout(title= "CandleStick Chart",
         yaxis = list(title = "Price",
                      tickformat = "digits"))

# Volume plot
cs2 <- kakao %>%   
  dplyr::mutate(direction = ifelse(Close >= Open, "Increasing", "Decreasing")) %>%
  plot_ly(x=~Date, y=~Volume, type='bar',
          color = ~direction, colors = c('blue','red'))  %>% 
  layout(yaxis = list(title = "Volume",
                      tickformat = "digits"),
         showlegend = FALSE)

subplot(cs1, cs2,  
        heights = c(0.7, 0.2), nrows=2,
        shareX = TRUE, titleY = TRUE )

Timezone


Version 1

kakao %>%
  plot_ly(x = ~Date, y = ~Close,
          type = 'scatter',
          mode = 'lines',
          fill = 'tozeroy',
          fillcolor='rgba(114, 186, 59, 0.5)',              
          line = list(color = 'rgb(114, 186, 59)'),
          text = ~paste("Date: ", Date, "<br>Close:", Close),         # Interactive Text
          hoverinfo = 'text') %>%
  layout(
    title = "",
    # plot_bgcolor = "#f8f8f8",
    yaxis = list(
      # title = "Close",
      zeroline = F,
      tickformat = "digits"
    ),
    xaxis = list(
      # title = "Date",
      # range = c(0,365),
      zeroline = F,
      showgrid = F
    )
  )

Version 2

accumulate_by <- function(dat, var) {
  var <- lazyeval::f_eval(var, dat)
  lvls <- plotly:::getLevels(var)
  dats <- lapply(seq_along(lvls), function(x) {
    cbind(dat[var %in% lvls[seq(1, x)], ], frame = lvls[[x]])
  })
  dplyr::bind_rows(dats)
}


df <- kakao %>%
  filter(Date >= today()-months(12))

df$ID <- 1:dim(df)[1]                         # 1부터 행 갯수만큼의 숫자NAdf <- df %>% accumulate_by(~Date) %>%         # Play에 맞게 그려질..
  mutate_at(vars(frame), as.character)

fig <- df %>% plot_ly(
  x = ~ID,
  y = ~Close,
  frame = ~frame,
  type = 'scatter',
  mode = 'lines',
  fill = 'tozeroy',
  fillcolor='rgba(114, 186, 59, 0.5)',
  line = list(color = 'rgb(114, 186, 59)'),
  text = ~paste("Date: ", Date, "<br>Close:", Close),      # Interactive Text
  hoverinfo = 'text'
) %>% layout(
  title = title,
  yaxis = list(
    title = "Close",
    zeroline = F
  ),
  xaxis = list(
    # type = 'date',
    # tickformat = ".",
    tickvals = list(df$ID),     # 원래 값 값
    ticktext = list(df$Date),   # 대응되는 바꿀값 (x축 바꾸기)    title = "Date",
    # range = c(0,365),
    zeroline = F,
    showgrid = F
  )
)
fig <- fig %>%
  animation_opts(
    frame = 1,        
    transition = 0,
    redraw = FALSE
  )
fig <- fig %>% animation_slider(
  currentvalue = list(
    prefix = "Date"
  )
)

fig

Line Plot


Version 1

plot_ly(kakao, type = 'scatter', mode = 'lines')%>%
  add_trace(x = ~Date, y = ~Close, name = 'KAKAO',
            line = list(color = "#663399", width = 2, dash = "dash"))%>%   
  layout(showlegend = F,
         xaxis = list(rangeslider = list(visible = T),   # X축 아래에 rangeslider 표시                          
                      rangeselector=list(                # 오른쪽 위에 버튼 표시시
                        buttons=list(
                          list(count=1, label="1m", step="month", stepmode="backward"),
                          list(count=6, label="6m", step="month", stepmode="backward"),
                          list(count=1, label="YTD", step="year", stepmode="todate"),   # 이번년도만list(count=1, label="1y", step="year", stepmode="backward"),
                          list(step="all")))),
         yaxis = list(
           tickformat = "digits"
         )) 

Version 2

accumulate_by <- function(dat, var) {
  var <- lazyeval::f_eval(var, dat)
  lvls <- plotly:::getLevels(var)
  dats <- lapply(seq_along(lvls), function(x) {
    cbind(dat[var %in% lvls[seq(1, x)], ], frame = lvls[[x]])
  })
  dplyr::bind_rows(dats)
}

df <- rbind( cbind(kakao, name = "kakao", "ID" = year(kakao$Date) + yday(kakao$Date)/366),
             cbind(samsung, name = "samsung", "ID" = year(samsung$Date) + yday(samsung$Date)/366)) %>%
  filter(Date >= today()-months(1)) 

df <- df %>%
  accumulate_by(~ID)

fig <- df %>%
  plot_ly(
    x = ~ID, 
    y = ~Close,
    split = ~name,
    frame = ~frame,
    type = 'scatter',
    mode = 'lines', 
    line = list(simplyfy = F)
  ) %>% layout(
  xaxis = list(
    zeroline = F
    # tickvals = list(df$ID),     # 원래 값# ticktext = list(df$Date)    # 대응되는 바꿀값 (x축 바꾸기)  ),
  yaxis = list(
    zeroline = F,
    tickformat = "digits"
  )
)  %>% animation_opts(
  frame = 200, 
  transition = 0, 
  redraw = FALSE
)
fig <- fig %>% animation_slider(
  hide = T
)
fig <- fig %>% animation_button(
  x = 1, xanchor = "right", y = 0, yanchor = "bottom"
)

fig

Bar Plot


Version 1

df  <- kakao %>%
  filter(Date >= today()-months(1)) %>%
  mutate( Return = c(NA, round( diff(Close)/ Close[1:(length(Close)-1)] *100, 2) )) %>%  # 맨 앞은 diff하면 무조건 NA
  mutate("Movement" = ifelse(Return > 0, "Up", "Down"))

plot_ly(df, x = ~Date, y = ~Return, type = 'bar', 
        color = ~Movement, colors = c("blue", "red"),
        text = ~Return, textposition = "outside")  %>%
  layout(yaxis = list(tickformat = "digits",
                      title = "Return (%)"),
         showlegend = FALSE)

Version 2

df <- data.frame("Date" = kakao$Date, "k.v" = kakao$Volume, "s.v" = samsung$Volume) %>%
  filter(Date >= today()-months(1)) 

plot_ly(df, x = ~Date, y = ~k.v, type = 'bar', name = 'kakao',
        marker = list(color = '#6666CC',
                      line = list(color = '#333399'))) %>% 
  add_trace(y = ~s.v, name = 'Samsung',
            marker = list(color = '#66CC66',
                          line = list(color = '#336633'))) %>% 
  layout(yaxis = list(title = "Volume",
                      tickformat = "digits" ))

Reuse

Text and figures are licensed under Creative Commons Attribution CC BY 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".