Plot inside of hoverinfo in Plotly - r

I've a plotly bar chart with a hover event which plots another plot alongside the first one
Is there a way to have the second plot show up inside of the hoverinfo box ?
The code I used is as under:
UI
library(shiny)
library(plotly)
library(shinythemes)
library(dplyr)
library(png)
ui <- fluidPage(
theme = shinytheme("spacelab"),
h2("Coupled hover-events in plotly charts using Shiny"),
tags$hr(),
fluidRow(
column(6, plotlyOutput(outputId = "ageplot", height = "600px")),
column(6, plotlyOutput(outputId = "raceplot", height = "600px"))),
tags$hr(),
tags$blockquote("Hover over age plot for race and gender information")
)
SERVER:
server <- function(input, output){
patdata <- read.csv("Sal.csv")
boston_race<-read.csv("bostonrace.csv")
patdata$Race<-ifelse(patdata$Race=="RACE_UNKNOWN", "Unknown",ifelse(patdata$Race=="BLACK_AFRICAN_AMERICAN", "African American",ifelse(patdata$Race=="RACE_LATINO_HISPANIC", "Latino Hispanic",
ifelse(patdata$Race=="WHITE", "White",ifelse(patdata$Race=="ASIAN", "Asian",
ifelse(patdata$Race=="RACE_OTHER", "Other","Unknown"))))))
patdata$Date<-as.Date(patdata$CreateDate, format = "%m/%d/%Y")
patdata$agegroup<- ifelse(patdata$Age>=0 &patdata$Age<=19,"<20",
ifelse(patdata$Age>=20 &patdata$Age<=29,"20-29",
ifelse(patdata$Age>=30 &patdata$Age<=39,"30-39",
ifelse(patdata$Age>=40 &patdata$Age<=49,"40-49",
ifelse(patdata$Age>=50,"50+","Invalid Age")))))
patdata$dp<- ifelse(patdata$Age>=0 &patdata$Age<=19,0,
ifelse(patdata$Age>=20 &patdata$Age<=29,1,
ifelse(patdata$Age>=30 &patdata$Age<=39,2,
ifelse(patdata$Age>=40 &patdata$Age<=49,3,
ifelse(patdata$Age>=50,4,NA)))))
patdata$dp<-as.numeric(patdata$dp)
patdata_age<- subset(patdata, select="agegroup")
patdata_age<-as.data.frame(table(patdata_age))
selection<-patdata_age
output$ageplot <- renderPlotly({
colnames(selection)<-c("agegroup","Freq")
selection$y<-round((patdata_age$Freq*100/sum(patdata_age$Freq)))
plot_ly(source = "source",selection, x = ~agegroup, y = selection$y, type = 'bar',
marker = list(color = 'rgb(255,140,0)',
# marker = list(color,alpha = d),
line = list(color = 'rgb(8,48,107)', width = 1.5))) %>%
layout(title = paste0("Age-group distribution of patients "),xaxis = list(title = 'age group'),
yaxis = list(title = paste0('Percentage of Patients')),titlefont=list(size=13),
annotations = list(x = ~agegroup, y = selection$y, text = paste0(selection$y, "%"),
xanchor = 'center', yanchor = 'bottom',
showarrow = FALSE))
})
output$raceplot <- renderPlotly({
eventdata <- event_data("plotly_hover", source = "source")
validate(need(!is.null(eventdata), "Hover over the age plot to populate this race plot"))
datapoint <- as.numeric(eventdata$pointNumber)[1]
sel<-patdata %>% filter(dp %in% datapoint)
raceselection<-subset(sel,select="Race")
raceselection<-as.data.frame(table(raceselection))
colnames(raceselection)<-c("Race","Freq")
raceselection$y<-round((raceselection$Freq*100/sum(raceselection$Freq)))
raceall<-merge(raceselection,boston_race)
raceall$Race<- as.character(raceall$Race)
raceall$Percent<-round(raceall$Percent,0)
plot_ly(raceall, x = ~Race, y = ~Percent, type = 'bar', name = 'Total Population',marker = list(color = 'rgb(255,140,0)',
line = list(color = 'rgb(8,48,107)', width = 1))
) %>%
add_trace(y = ~y, name = 'Patient Population',marker = list(color = 'rgb(49,130,189)',
line = list(color = 'rgb(8,48,107)', width = 1))) %>%
layout(yaxis = list(title = 'Population Percent'), barmode = 'group',
title = paste0("Patient Race comparison"))
})
}
boston_race dataset:
Race Percent
White 47
Unknown 0
Other 1.8
Latino Hispanic 17.5
Asian 8.9
African American 22.4
Sal data snippet:
CreateDate Age Race
1/6/1901 20 RACE_LATINO_HISPANIC
1/21/1901 37 BLACK_AFRICAN_AMERICAN
1/21/1901 51 WHITE
1/31/1901 58 WHITE
2/2/1901 24 ASIAN
2/4/1901 31 WHITE
2/7/1901 29 WHITE
2/7/1901 19 WHITE
2/11/1901 7 BLACK_AFRICAN_AMERICAN
2/12/1901 41 ASIAN
2/13/1901 22 WHITE
2/19/1901 3 RACE_LATINO_HISPANIC
2/24/1901 19 WHITE
3/7/1901 26 WHITE
3/12/1901 21 RACE_UNKNOWN
3/17/1901 39 RACE_LATINO_HISPANIC
3/18/1901 71 WHITE
3/20/1901 65 WHITE
4/10/1901 19 WHITE
4/18/1901 31 WHITE
4/23/1901 63 WHITE
4/24/1901 20 WHITE
4/29/1901 19 WHITE
4/30/1901 27 WHITE
5/2/1901 23 WHITE
5/12/1901 21 WHITE
5/16/1901 26 RACE_LATINO_HISPANIC
5/20/1901 54 BLACK_AFRICAN_AMERICAN
5/20/1901 2 WHITE
5/20/1901 9 RACE_LATINO_HISPANIC
5/21/1901 28 WHITE
5/29/1901 2 BLACK_AFRICAN_AMERICAN
5/30/1901 0 WHITE
6/3/1901 21 WHITE
6/9/1901 10 ASIAN
6/9/1901 37 WHITE
The current output:
I want the second plot to appear in a small hoverinfo box

Related

How do I make an interactive radar chart in r shiny?

I'm pretty new to r and shiny and I am currently working on my first personal project. My project is about Pokemon and I am currently having trouble creating an interactive radar chart. I have tried looking at other questions about on this website about r and radar charts but couldn't really find the right answer since the dataset was usually in a different format, and the answers didn't provide a way to do it interactively.
What I'm trying to achieve: Create an interactive radar chart where the user can select a Pokemon and the radar chart will display that Pokemon's base stats (hp, attack, defense, etc.)
dataset:
name hp defense attack sp_attack sp_defense speed
1 Bulbasaur 45 49 49 65 65 45
2 Ivysaur 60 63 62 80 80 60
3 Venusaur 80 123 100 122 120 80
4 Charmander 39 43 52 60 50 65
5 Charmeleon 58 58 64 80 65 80
6 Charizard 78 78 104 159 115 100
...
ui.R:
library(shiny)
library(plotly)
ui <- navbarPage(title = "Pokemon Research",
tabPanel(title = "Types and Stats",
sidebarPanel(
selectInput(inputId = "diff_stat",
label = "Different Types and their Base Statistics",
choices = c("hp", "attack", "defense", "special_attack",
"special_defense", "speed", "total"))
),
mainPanel(plotlyOutput("type"))),
tabPanel(title = "Pokemon Statistics",
sidebarPanel(
selectInput(inputId = "indv",
label = "Pokemon",
choices = data$name
),
#IDK WHAT TO PUT HERE FOR THE MAINPANEL
)))
server.R:
library("shiny")
library("ggplot2")
data <- read.csv("../data/pokemon.csv", stringsAsFactors = FALSE)
type_data <- data %>%
select(name, type1, hp, defense, attack, sp_attack, sp_defense, speed) %>%
group_by(type1) %>%
summarise(hp = mean(hp),
attack = mean(attack),
defense = mean(defense),
special_attack = mean(sp_attack),
special_defense = mean(sp_defense),
speed = mean(speed),
total = mean(attack + defense + hp + sp_attack + sp_defense + speed))
indv_data <- data %>%
select(name, hp, defense, attack, sp_attack, sp_defense, speed)
server <- function(input, output) {
output$type <- renderPlotly({
ggplot(data = type_data, mapping = aes_string(x = "type1", y = input$diff_stat)) +
geom_line(group = 1) +
geom_point() +
labs(x = "Types",
y = "Base Stat (avg)")
})
output$radar <- renderPlot({
#WHAT DO I PUT HERE TO MAKE THE RADAR CHART
})
}
Any help is greatly appreciated!
This can help. I only included the code for the radar chart.
library(tidyverse)
library(shiny)
library(plotly)
pokemons <-
read_table('
name hp defense attack sp_attack sp_defense speed
Bulbasaur 45 49 49 65 65 45
Ivysaur 60 63 62 80 80 60
Venusaur 80 123 100 122 120 80
Charmander 39 43 52 60 50 65
Charmeleon 58 58 64 80 65 80
Charizard 78 78 104 159 115 100')
ui <- navbarPage(title = "Pokemon Research",
tabPanel(title = "Pokemon Statistics",
sidebarPanel(
selectInput(inputId = "indv",
label = "Pokemon",
choices = pokemons$name,
selected = 'Bulbasaur')
),
mainPanel(
plotlyOutput('radar') #the radar plot
)
))
server <- function(input, output, session) {
output$radar <- renderPlotly({
pkmn <- filter(pokemons, name == input$indv)
r <- map_dbl(pkmn[, 2:6], ~.x)
nms <- names(r)
#code to plot the radar
fig <- plot_ly(
type = 'scatterpolar',
r = r,
theta = nms,
fill = 'toself',
mode = 'markers'
)
fig <- fig %>%
layout(
polar = list(
radialaxis = list(
visible = T,
range = c(0,max(r))
)
),
showlegend = F
)
})
}
shinyApp(ui, server)

plotly: Map size (shape) to value colum in scatterplot

I really appreaciate the 'plotly' r-package. Currently I run into an issue, where I want to visualize a data frame as points and map the point size (as well as the shape potentially) to a dimension of the data frame.
The problem I run into with my own dataset is, that the sizes are somehow "mixed up" in the sense, that the bigger points don't correspond to the bigger values.
I haven't fully understood the options I have with plotly (sizeref and other marker-options; the fundamental difference between mapping the dimension directly or in the marker arguments; etc) , so this is my best shot as a minimal example right here.
(The second plot is closer to what I currently do. If this one could be fixed, it would be preferable to me)
Your thoughts are greatly appreciated. :)
library(plotly)
set.seed(1)
df <- data.frame(x = 1:10,
y = rep(c("id1", "id2"), 5),
col = factor(sample(3, 10, replace = TRUE)))
df$size <- c(40, 40, 40, 30, 30, 30, 20, 20, 20, 10)
df
#> x y col size
#> 1 1 id1 1 40
#> 2 2 id2 2 40
#> 3 3 id1 2 40
#> 4 4 id2 3 30
#> 5 5 id1 1 30
#> 6 6 id2 3 30
#> 7 7 id1 3 20
#> 8 8 id2 2 20
#> 9 9 id1 2 20
#> 10 10 id2 1 10
# Mapping looks right, but the size may not be correct
plot_ly(df,
x = ~x,
y = ~y,
color = ~col,
size = ~size,
type = 'scatter',
mode = 'markers',
hoverinfo = "text",
text = ~paste('</br> x: ', x,
'</br> y: ', y,
'</br> col: ', col,
'</br> size: ', size)
# , marker = list(size = ~size)
)
# Size looks right, but mapping to points is wrong
plot_ly(df,
x = ~x,
y = ~y,
color = ~col,
# size = ~size,
type = 'scatter',
mode = 'markers',
hoverinfo = "text",
text = ~paste('</br> x: ', x,
'</br> y: ', y,
'</br> col: ', col,
'</br> size: ', size)
, marker = list(size = ~size)
)
devtools::session_info() # excerpt
#> plotly * 4.8.0

Plot values are not being generated by my code using R studio, plotly in R, and 'parcoords'

I'm having trouble with plotly in R and 'parcoords'. I'm trying to plot using colorscale defined by Persona. Persona has values of 1 through 4 and I expect each number to have it's own color. The plot scales fine but there are no lines representing the values for each variable.
Here is the code
options(viewer=NULL)
p <- df %>%
plot_ly(type = 'parcoords',
line = list(color = ~Persona,
colorscale = list(c(0,'red'),c(0.5,'green'),c(1,'blue'),c(1.5,'yellow'))) ,
dimensions = list(
list(range = c(15,55),
label = 'Rescuer Count', values = ~RescuerCount),
list(range = c(15,50),
label = 'Rescuer Share', values = ~RescuerShare),
list(range = c(5,95),
label = 'Avg Serviced Zip Codes', values = ~AvgServZips),
list(range = c(10,925),
label = 'Avg Number of Rescues', values = ~ AAvgNumofRescues),
list(range = c(310,16000),
label = 'Avg Rescuer Earnings', values = ~ AAEarnings),
list(range = c(1,55),
label = 'Persona Share of Earnings', values = ~ EarnShare),
list(range = c(30,95),
label = ' Login Percentage', values = ~ LoginPrct),
list(range = c(7,95),
label = 'Prct of Login Days W/Offer', values = ~ PrctLoginDaysWO),
list(range = c(1,5),
label = 'Avg Acceptance Rate', values = ~ AvgAcceptRate),
list(range = c(150,1975),
label = 'Annualized Number of Offers', values = ~ ANumofOffers)
)
)
print(p)
Data Table is here
Persona RescuerCount RescuerShare AvgServZips AAvgNumofRescues AAEarnings EarnShare LoginPrct PrctLoginDaysWO AvgAcceptRate ANumofOffers
1 16 15 45 389 6706 27 71 91 30 1314
2 13 15 90 915 15805 51 91 94 47 1954
3 30 27 28 147 2429 18 55 86 22 679
4 51 46 6 20 319 4 34 75 13 152
resulting plot
Please Help

Plotly - Plot 2 Y Axes With Time Series

I am trying to use r plotly to plot a chart that has following features:
Date objects as X-variable
2 line plots in one charts with 2 Y-axis: one on the left, the other on the right
Date Amount1 Amount2
2/1/2017 19251130 21698.94
2/2/2017 26429396 10687.37
2/5/2017 669252 0.00
2/6/2017 25944054 11885.10
2/7/2017 27895562 14570.39
2/8/2017 20842279 20080.56
2/9/2017 25485527 9570.51
2/10/2017 17008478 14847.49
2/11/2017 172562 0.00
2/12/2017 379397 900.00
2/13/2017 25362794 18390.80
2/14/2017 26740881 11490.94
2/15/2017 20539413 22358.26
2/16/2017 22589808 12450.45
2/17/2017 18290862 3023.45
2/19/2017 1047087 775.00
2/20/2017 4159070 4100.00
2/21/2017 28488401 22750.35
and the code I use is:
ay <- list(
#tickfont = list(color = "red"),
overlaying = "y",
side = "right"
)
p <- plot_ly() %>%
add_lines(x = df$Date, y = df$Amount1, name = "Amount1",type = "scatter", mode = "lines") %>%
add_lines(x = df$Date, y = df$Amount2, name = "Amount2", yaxis = "y2",type = "scatter", mode = "lines") %>%
layout(
title = "Chart Summary", yaxis2 = ay,
xaxis = list(title="Date")
)
The output chart looks fine but the date intervals on the X-axis is looking bad. I am wondering what is the solution to this, and if I want to have 2 histograms in one chart using the data above, what is the optimal way to do it?
Thank you for help!
Is your Date column a string or date?
If it is a string, convert it to date and let Plotly take care of it.
df$Date <- as.Date(df$Date , "%m/%d/%Y")
Full code
library('plotly')
txt <- "Date Amount1 Amount2
2/1/2017 19251130 21698.94
2/2/2017 26429396 10687.37
2/5/2017 669252 0
2/6/2017 25944054 11885.1
2/7/2017 27895562 14570.39
2/8/2017 20842279 20080.56
2/9/2017 25485527 9570.51
2/10/2017 17008478 14847.49
2/11/2017 172562 0
2/12/2017 379397 900
2/13/2017 25362794 18390.8
2/14/2017 26740881 11490.94
2/15/2017 20539413 22358.26
2/16/2017 22589808 12450.45
2/17/2017 18290862 3023.45
2/19/2017 1047087 775
2/20/2017 4159070 4100
2/21/2017 28488401 22750.35"
df$Date <- as.Date(df$Date , "%m/%d/%Y")
ay <- list(
#tickfont = list(color = "red"),
overlaying = "y",
side = "right"
)
p <- plot_ly() %>%
add_lines(x = df$Date, y = df$Amount1, name = "Amount1",type = "scatter", mode = "lines") %>%
add_lines(x = df$Date, y = df$Amount2, name = "Amount2", yaxis = "y2",type = "scatter", mode = "lines") %>%
layout(
title = "Chart Summary", yaxis2 = ay,
xaxis = list(title="Date", ticks=df$Date)
)
p

Font Coloring Using xlsx Package in R

I am writing an R function to save out pre-formatted data frames. Part of the format template calls for changing the column heading font color. The cell styling returns the correct alignment and bolding, but the text is still black.
The below is a bare version to demonstrate my font coloring problem (just change the file_path variable to a location that exists).
library(xlsx)
file_path <- "C:/Users/.../Desktop/tst.xlsx"
wb <- createWorkbook()
headerStyle <- CellStyle(wb,
font = Font(wb, isBold=TRUE, color = "#ffffff"),
fill = Fill(foregroundColor = "#2db6e8",
pattern = "SOLID_FOREGROUND"),
alignment = Alignment(wrapText = TRUE,
horizontal = "ALIGN_CENTER",
vertical = "VERTICAL_CENTER")
)
x <- mtcars
sheet <- createSheet(wb, "test")
cellBlock <- CellBlock(sheet,
startRow = 1,
startCol = 1,
noRows = nrow(x) + 1,
noColumns = ncol(x) + 1,
create = TRUE)
CB.setRowData(cellBlock = cellBlock,
x = colnames(x),
rowIndex = 1,
colOffset = 1,
rowStyle = headerStyle +
Border(pen = "BORDER_MEDIUM", color = "black",
position = "BOTTOM"))
saveWorkbook(wb, file_path)
I was able to get white text using the color index from the INDEXED_COLORS_ constant which is 9 for white. For your example code it would read:
headerStyle <- CellStyle(wb,
font = Font(wb, isBold=TRUE, color = "9"),
fill = Fill(foregroundColor = "#2db6e8",
pattern = "SOLID_FOREGROUND"),
alignment = Alignment(wrapText = TRUE,
horizontal = "ALIGN_CENTER",
vertical = "VERTICAL_CENTER")
)
It seems to relate uniquely to white text. Try using different colors:
headerStyle <- CellStyle(wb,
font = Font(wb, isBold=TRUE, color = "grey"),
fill = Fill(foregroundColor = "#2db6e8",
pattern = "SOLID_FOREGROUND"),
alignment = Alignment(wrapText = TRUE,
horizontal = "ALIGN_CENTER",
vertical = "VERTICAL_CENTER")
)
It works with orange, grey, blue, but not white. This may be an effort to prevent text from being invisible if the background were the default white, but I can't say for certain. Perhaps the package creator can comment.
The constants used by the xlsx package are define in these groups:
HALIGN_STYLES_
VALIGN_STYLES_
BORDER_STYLES_
FILL_STYLES_
CELL_STYLES_
INDEXED_COLORS_
So, just displaying them in the console for INDEX_COLORS_ you get
BLACK WHITE RED BRIGHT_GREEN BLUE YELLOW
8 9 10 11 12 13
PINK TURQUOISE DARK_RED GREEN DARK_BLUE DARK_YELLOW
14 15 16 17 18 19
VIOLET TEAL GREY_25_PERCENT GREY_50_PERCENT CORNFLOWER_BLUE MAROON
20 21 22 23 24 25
LEMON_CHIFFON ORCHID CORAL ROYAL_BLUE LIGHT_CORNFLOWER_BLUE SKY_BLUE
26 28 29 30 31 40
LIGHT_TURQUOISE LIGHT_GREEN LIGHT_YELLOW PALE_BLUE ROSE LAVENDER
41 42 43 44 45 46
TAN LIGHT_BLUE AQUA LIME GOLD LIGHT_ORANGE
47 48 49 50 51 52
ORANGE BLUE_GREY GREY_40_PERCENT DARK_TEAL SEA_GREEN DARK_GREEN
53 54 55 56 57 58
OLIVE_GREEN BROWN PLUM INDIGO GREY_80_PERCENT AUTOMATIC
59 60 61 62 63 64
You can use numeric or alias style:
cs2 <- CellStyle(wb) +
Font(
wb,
heightInPoints = 12,
isBold = F,
isItalic = F,
name = "Arial",
color="ORANGE"
)
cs2 <- CellStyle(wb) +
Font(
wb,
heightInPoints = 12,
isBold = F,
isItalic = F,
name = "Arial",
color=59
)

Resources