Additional tooltip information in highcharter stock - r

I am currently building an app and I want to have tooltips in a highcharter stock with additional information.
#Data
df <- data.frame(time = seq(as.Date("2021-03-10"), length = 10, by = "days"),
values = 1:10,
additionalInfo1 = LETTERS[1:10],
additionalInfo2 = letters[1:10])
#Packages
library(highcharter) #plots
library(xts) #conversion for stock-highchart
library(dplyr) #piping-operator
I know how to add additional information to a tooltip when using type="line". This can be done via
highchart_line <- hchart(df, "line", hcaes(x = time, y = values),
tooltip = list(headerFormat = "<b> Some Tooltipheader </b> <br/>",
pointFormat = paste0("index: {point.index} <br/>",
"time: {point.time} <br/>",
"additional1: {point.additionalInfo1} <br/>",
"additional2: {point.additionalInfo2}")))
and shows everything fine. The nice thing is that one can supply the whole data and hence has access to the columnnames.
When creating a type="stock", I need to convert the data to an xts while only using the times and the values:
stockdata_xts <- xts(x = df$values, order.by = df$time)
highchart_stock <- highchart(type="stock") %>%
hc_add_series(stockdata_xts, name = "someData",
tooltip = list(pointFormat = paste0(
"point.x: {point.x} <br/>",
"point.y: {point.y} <br/>",
"point.index: {point.index} <br/>"
))) %>%
hc_rangeSelector(enabled = FALSE)
Is there a way to put additional data for the tooltip in the stock-highchart such that the tooltip looks like the one in the linechart above? Maybe some functionality of the xts-object including more attributes for it which I don't know.
The reason why I want to use the stock-highchart is the navigator-bar. If there is a way to include the navigator-bar in the line-highchart, I would also be thankful. There is also a function highcharter::hc_navigator, but the documentation says that it is only applicable to highstocks. (see https://cloud.r-project.org/web/packages/highcharter/highcharter.pdf , page 50)

Yes, the navigator works in stockChart. For such tooltip customization, I think it will be best to use the dedicated formatter API function: https://api.highcharts.com/highstock/tooltip.formatter
Here you can find an article that can help you use JS code in R:
https://www.highcharts.com/blog/tutorials/working-with-highcharts-javascript-syntax-in-r/?fbclid=IwAR1Em2yNUsIJunTRS4IEbUwGksb5PC7LfZATLcyvb7uLS7ZvV7v4-e0L0

Related

Display value other than 'size' with sunburstR

The following code generates a simple, interactive sunburst using sunburstR (example taken from https://timelyportfolio.github.io/sunburstR/articles/sunburst-2-0-0.html). When you scroll over any section it displays "size", and also wedges are colored according to "size". I would like to be able to manually specify a value other than 'size' that will come up when scrolled over and also that will be used to color the wedges. Is this possible? In other words, I would like to be able to have all wedges the same size, but be able to specify a different value for each wedge.
library(sunburstR)
library(htmltools)
library(d3r)
dat <- data.frame(
level1 = rep(c("a", "b"), each=3),
level2 = paste0(rep(c("a", "b"), each=3), 1:3),
size = c(10,5,2,3,8,6),
stringsAsFactors = FALSE
)
knitr::kable(dat)
tree <- d3_nest(dat, value_cols = "size")
tree
sb1 <- sunburst(tree, width="100%", height=400)
sb1
Just now seeing this and sorry for the delay. We can specify another field other than size with the valueField argument. See https://bl.ocks.org/timelyportfolio/616fc81b3bacee0d34a2975d53e9203a as an example.
library(treemap)
library(sunburstR)
library(d3r)
# use example from ?treemap::treemap
data(GNI2014)
tm <- treemap(GNI2014,
index=c("continent", "iso3"),
vSize="population",
vColor="continent",
type="index")
tm_nest <- d3_nest(
tm$tm[,c("continent", "iso3", "vSize", "color")],
value_cols = c("vSize", "color")
)
sunburst(
jsondata = tm_nest,
valueField = "vSize",
count = TRUE,
colors = htmlwidgets::JS("function(d){return d3.select(this).datum().color;}")
)
The prior example also shows how we can change color based on a column in the data.frame using a JavaScript function.
Here is another example controlling color https://github.com/timelyportfolio/sunburstR/issues/17#issuecomment-228448029.

How to create a reusable plot_ly function?

I am looking at a dataset from tidytuesday, available here:
video_games <- readr::read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-07-30/video_games.csv")
I wrote this code to create a horizontal bar plot, ranked in descending order.
video_games %>%
top_n(10, metascore) %>%
arrange(desc(metascore)) %>%
plot_ly(x = ~metascore, y = ~fct_reorder(game, metascore),
type = "bar") %>%
layout(xaxis = list(title = "Metascore"),
yaxis = list(title = ""))
I want to reuse the code with multiple variables without copying and pasting, so I created a function with 2 entries for the variables I want to plot. (I left out the layout section. If there is a way to automatically re-lable the plot inside the function, that would be cool.)
video_games_ranking_plot <- function(A, B) {
top_n(10, A) %>%
arrange(desc(A)) %>%
plot_ly(x = ~A, y = ~fct_reorder(B, A),
type = "bar")
}
When I run the function
video_games %>%
video_games_ranking_plot(metascore, game)
... I get the error message Error in video_games_ranking_plot(., metascore, game) :
unused argument (game)
Does anyone know why?
The source of the problem seems to be that you are passing the same arguments metascore, game of one type to very different elements of your custom function that accepts arguments of different types:
top_n(10, metascore)
arrange(desc(metascore)
plot_ly(x = ~metascore, y = ~fct_reorder(game, metascore)
The fact that you are also passing columns ase arguments using piping can also pose certain challenges. I haven't found the time to build a complete solution, but hopefully this will help you on your way to a complete solution:
Plot:
Code:
library(dplyr)
library(forcats)
library(plotly)
# get data
video_games <- readr::read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-07-30/video_games.csv")
data <- video_games
# custom function
video_games_ranking_plot <- function(data, topn, col_top, col_ord){
# select and arrand data
df <- data %>% top_n(topn, {{col_top}}) %>% arrange(desc({{col_ord}})) #%>%
col_top_name <- deparse(substitute(col_top))
col_ord_name <- deparse(substitute(col_ord))
df2<- df[c(col_top_name, col_ord_name)]
# build plotly pliot
p <- plot_ly(x = df2[[col_top_name]], y = df2[[col_ord_name]], type = "bar")
}
plt <- video_games_ranking_plot(data=video_games, topn=5, metascore, game)
plt
There's still an issue with the ~fct_reorder(game, metascore) part.
I had to raise a question myself to even get this far. Take a look at the answer from user Ronak Shah to the post How to pass a dataframe column as an argument in a function using piping? to learn more on how to pass arguments to piping functions.
I hope this helps!

How to get the grouping right in R with Plotly

I have some problem to group my data in Plotly under R. To start with I was using local data from a csv file, reading them with:
geogrid_data <- read.delim('geogrid.csv', row.names = NULL, stringsAsFactors = TRUE)
and the plotting went well, using the following:
library(plotly)
library(RColorBrewer)
x <- list(
title = 'Date'
)
p <- plotly::plot_ly(geogrid_data,
type = 'scatter',
x = ~ts_now,
y = ~absolute_v_sum,
text = paste('Table: ', geogrid_data$table_name,
'<br>Absolute_v_Sum: ', geogrid_data$absolute_v_sum),
hoverinfo = 'text',
mode = 'lines',
color = list(
color = colorRampPalette(RColorBrewer::brewer.pal(11,'Spectral'))(
length(unique(geogrid_data$table_name))
)
),
transforms = list(
list(
type = 'groupby',
groups = ~table_name
)
)
) %>% layout(showlegend = TRUE, xaxis = x)
Here the output:
Then I was going to alter the data source to an Oracle database table, reading the data as follows, using the ROracle package:
# retrieve data into resultSet object
rs <- dbSendQuery(con, "SELECT * FROM GEOGRID_STATS")
# fetch records from the resultSet into a data.frame
geogrid_data <- fetch(rs)
# free resources occupied by resultSet
dbClearResult(rs)
dbUnloadDriver(drv)
# remove duplicates from dataframe (based on TABLE_NAME, TS_BEFORE, TS_NOW, NOW_SUM)
geogrid_data <- geogrid_data %>% distinct(TABLE_NAME, TS_BEFORE, TS_NOW, NOW_SUM, .keep_all = TRUE)
# alter date columns in place
geogrid_data$TS_BEFORE <- as.Date(geogrid_data$TS_BEFORE, format='%d-%m-%Y')
geogrid_data$TS_NOW <- as.Date(geogrid_data$TS_NOW, format='%d-%m-%Y')
and adjusting the plotting to:
p <- plotly::plot_ly(
type = 'scatter',
x = geogrid_data$TS_NOW,
y = geogrid_data$ABSOLUTE_V_SUM,
text = paste('Table: ', geogrid_data$TABLE_NAME,
'<br>Absolute_v_Sum: ', geogrid_data$ABSOLUTE_V_SUM,
'<br>Date: ', geogrid_data$TS_NOW),
hoverinfo = 'text',
mode = 'lines',
color = list(
color = colorRampPalette(RColorBrewer::brewer.pal(11,'Spectral'))(
length(unique(geogrid_data$TABLE_NAME))
)
),
transforms = list(
list(
type = 'groupby',
groups = geogrid_data$TABLE_NAME
)
)
) %>% layout(showlegend = TRUE, xaxis = x)
Unfortunately, this is leading to some problem with the grouping as it seems.:
As you can see from the label text when hovering over the data point, the point represents data from NY_SKOV_PLANTEB_MW_POLY while the legend is set to show data from NY_BYGN_MW_POLY. Looking at other data points in this graph I found a wild mix of points of all sorts in this graph, some of them representing data of NY_BYGN_MW_POLY, most of them not.
Also the plotting with respect to the time line does not work any more, e.g. data are plotted with start on Dec. 11 - Dec. 10 - Dec. 10 - Dec. 12 - Dec. 20 - Dec. 17 - Dec. 16 - Dec. 15.
Where do I go wrong in handling the data, and what do I have to do to get it right?
Of course, one should look at the data... thanks Marco, after your question I did look at my data.
There are some points where I simply assumed things.
The reason why all data plotted fine with data from the csv file is simple. All information manually compiled in the csv file came from information in emails that have been ordered by date. Hence, I compiled the data in the csv file ordered by date and Plotly does not have any problems grouping the data by table_name.
After looking at my data I tidied up, keeping only the data I need to show in the plot and used dplyr to sort the data by time.
geogrid_data <- dplyr::arrange(geogrid_data, TS_NOW)
It is only by time and not by time and table name because the sorting by table name is done anyway by Plotly and the groupby statement

How to control the size of the vertex label in textplot_network?

I am able to control the vertex size, but not the vertex label size in textplot_network. Is there a way of doing it?
I saw the argument vertex.cex in plot.network but it doesn't work.
This is what I have got so far:
library(quanteda)
toks <- corpus_subset(data_corpus_irishbudget2010) %>%
tokens(remove_punct = TRUE) %>%
tokens_tolower() %>%
tokens_remove(stopwords("english"), padding = FALSE)
myfcm <- fcm(toks, context = "window", tri = FALSE)
feat <- names(topfeatures(myfcm, 30))
myfcm <- fcm_select(myfcm, feat, verbose = FALSE)
textplot_network(myfcm, vertex_size = rowSums(myfcm)/min(rowSums(myfcm)),
vertex.cex = rowSums(myfcm)/min(rowSums(myfcm)))
As you can see from the source code, the font size is not an argument you can control in the function.
https://github.com/quanteda/quanteda/blob/master/R/textplot_network.R#L242-L256
If you really need the feature, please file a feature request here:
https://github.com/quanteda/quanteda/issues/new/choose
If you switch to the visNetwork package instead in R - you can use the additional argument of Node Label Size - it also has a JS based back end so is useful for the other elements of text labelling

How to change chart height in hchart() function in R (highcharter package) without using pipe operator?

I built a Shiny app where I create some plot from hist() and density() objects, both saved in a list into an .RDS file from another script file. So, in shiny I only read the .RDS and make the plot.
Everything is working now, except that I am not finding how to change the height of the highchart plot using the hchart() function. In my code, the way it was built, I cannot work with pipes "%>%", beacuse I am using hchart inside a purrr::map() function.
To explain better I created a small example, that follows.
# Example of how the objects are structured
list <-
list(df1 = list(Sepal.Length = hist(iris$Sepal.Length, plot = FALSE)),
df2 = list(Sepal.Length = density(iris$Sepal.Length)))
# Example of a plot built with hchart function
list[['df2']]['Sepal.Length'] %>%
purrr::map(hchart, showInLegend = FALSE)
# Example of what does not work
list[['df2']]['Sepal.Length'] %>%
purrr::map(hchart, showInLegend = FALSE, height = 200)
Actually, I also would like to change more options of the chart, like colors, for example. But I am not finding a way with this solution I found.
Thanks in advance.
Wlademir.
I can see 2 main ways to do what you need (not sure why you can't use the pipe):
Option 1
Create a function to process every data and add the options inside that function:
get_hc <- function(d) {
hchart(d, showInLegend = FALSE) %>%
hc_size(height= 200) %>%
hc_title(text = "Purrr rocks")
}
Then:
list_of_charts <- list[['df2']]['Sepal.Length'] %>%
purrr::map(get_hc)
Option 2
You can use successively purrr::map:
list_of_charts <- list[['df2']]['Sepal.Length'] %>%
purrr::map(hchart, showInLegend = FALSE)
# change heigth
list_of_charts <- purrr::map(list_of_charts, hc_size, height = 200)
# change title
list_of_charts <- purrr::map(list_of_charts, hc_title. text = "Purrr rocks")
Or you can use successively purrr::map/ %>% combo:
list_of_charts <- list[['df2']]['Sepal.Length'] %>%
purrr::map(hchart, showInLegend = FALSE) %>%
purrr::map(hc_size, height = 200) %>%
purrr::map(hc_title, text = "Purrr rocks")

Resources