jbkunst / highcharter

R wrapper for highcharts
http://jkunst.com/highcharter/
Other
719 stars 148 forks source link

hc_add_theme() works differently with hchart() and highchart() #302

Closed dpprdan closed 7 years ago

dpprdan commented 7 years ago

hchart() and highchart() seem to have different default chart layouts. This is a problem if one wants to combine different graphs with both methods on one page and also introduces a bug in the handling of themes in hchart (see below).

To illustrate, let's start with a simple highchart() example:

library("tidyverse")
library("highcharter")
data(citytemp)

citytemp$int <- seq_len(12L)

glimpse(citytemp)

hc_highchart <- highchart() %>% 
  hc_xAxis(categories = citytemp$int) %>% 
  hc_add_series(name = "Berlin", data = citytemp$berlin) %>% 
  hc_add_series(name = "Tokyo", data = citytemp$tokyo) 

hc_highchart

The resulting graph on my system: grafik

Now this should give the same chart with hchart() (yes, the resulting objects differ, but the graph layout should still be the same, IMHO):

hc_hchart <- citytemp %>% 
  select(-new_york,-london) %>% 
  gather(city, temp, tokyo, berlin) %>%
  hchart("line", 
         hcaes(x = int, y = temp, group = city)
         )

hc_hchart

grafik

Notice the missing markers and the different tickmarks on the x-axis. Also the number of tick-labels on the x-axis are reduced (and this is not due to the sightly reduced space due to the y-axis label).

In addition, it is not possible to add the markers via a theme to the hchart() object.

thm <- hc_theme(
  # apparently a theme does not work without a chart option
  chart = list(backgroundColor = "#eeeeee"),
  plotOptions = 
    list(
      line = 
        list(
          marker = 
            list(
              enabled = TRUE
              )
          )
      )
  )

hc_hchart %>% hc_add_theme(thm)

grafik

Notice the grey background, but missing markers.

Now let's see whether the code works with the highchart() object. (I disable the markers in the theme now, since they are enabled by default).

thm_nomark <- hc_theme(
  chart = list(backgroundColor = "#eeeeee"),
  plotOptions = 
    list(
      line = 
        list(
          marker = 
            list(
              enabled = FALSE
              )
          )
      )
  )

hc_highchart %>% hc_add_theme(thm_nomark)

grafik

> devtools::session_info()
Session info -------------------------------------------------------------------------------------------------
 setting  value                       
 version  R version 3.3.3 (2017-03-06)
 system   x86_64, mingw32             
 ui       RStudio (1.0.136)           
 language (EN)                        
 collate  German_Germany.1252         
 tz       Europe/Berlin               
 date     2017-04-24                  

Packages -----------------------------------------------------------------------------------------------------
 package     * version    date       source                          
 assertthat    0.2.0      2017-04-11 CRAN (R 3.3.3)                  
 backports     1.0.5      2017-01-18 CRAN (R 3.3.2)                  
 broom         0.4.2      2017-02-13 CRAN (R 3.3.2)                  
 cellranger    1.1.0      2016-07-27 CRAN (R 3.3.3)                  
 colorspace    1.3-2      2016-12-14 CRAN (R 3.3.2)                  
 data.table    1.10.4     2017-02-01 CRAN (R 3.3.2)                  
 DBI           0.6-1      2017-04-01 CRAN (R 3.3.3)                  
 devtools      1.12.0     2016-06-24 CRAN (R 3.3.1)                  
 digest        0.6.12     2017-01-27 CRAN (R 3.3.2)                  
 dplyr       * 0.5.0      2016-06-24 CRAN (R 3.3.1)                  
 forcats       0.2.0      2017-01-23 CRAN (R 3.3.2)                  
 foreign       0.8-67     2016-09-13 CRAN (R 3.3.1)                  
 ggplot2     * 2.2.1      2016-12-30 CRAN (R 3.3.2)                  
 gtable        0.2.0      2016-02-26 CRAN (R 3.3.0)                  
 haven         1.0.0      2016-09-23 CRAN (R 3.3.1)                  
 here        * 0.0-6      2017-02-20 Github (krlmlr/here@007bfd9)    
 highcharter * 0.5.0      2017-01-17 CRAN (R 3.3.3)                  
 hms           0.3        2016-11-22 CRAN (R 3.3.2)                  
 htmltools     0.3.5      2016-03-21 CRAN (R 3.3.0)                  
 htmlwidgets   0.8        2016-11-09 CRAN (R 3.3.2)                  
 httr          1.2.1      2016-07-03 CRAN (R 3.3.1)                  
 igraph        1.0.1      2015-06-26 CRAN (R 3.3.0)                  
 jsonlite      1.4        2017-04-08 CRAN (R 3.3.3)                  
 knitr         1.15.1     2016-11-22 CRAN (R 3.3.2)                  
 lattice       0.20-35    2017-03-25 CRAN (R 3.3.3)                  
 lazyeval      0.2.0.9000 2016-06-23 Github (hadley/lazyeval@c155c3d)
 lubridate     1.6.0      2016-09-13 CRAN (R 3.3.1)                  
 magrittr      1.5        2014-11-22 CRAN (R 3.3.0)                  
 memoise       1.0.0      2016-01-29 CRAN (R 3.3.1)                  
 mnormt        1.5-5      2016-10-15 CRAN (R 3.3.1)                  
 modelr        0.1.0      2016-08-31 CRAN (R 3.3.1)                  
 munsell       0.4.3      2016-02-13 CRAN (R 3.3.0)                  
 nlme          3.1-131    2017-02-06 CRAN (R 3.3.2)                  
 pacman      * 0.4.1      2016-03-30 CRAN (R 3.3.0)                  
 plyr          1.8.4      2016-06-08 CRAN (R 3.3.1)                  
 psych         1.7.3.21   2017-03-22 CRAN (R 3.3.3)                  
 purrr       * 0.2.2      2016-06-18 CRAN (R 3.3.1)                  
 quantmod      0.4-7      2016-10-24 CRAN (R 3.3.3)                  
 R6            2.2.0      2016-10-05 CRAN (R 3.3.1)                  
 Rcpp          0.12.10    2017-03-19 CRAN (R 3.3.3)                  
 readr       * 1.1.0      2017-03-22 CRAN (R 3.3.3)                  
 readxl        1.0.0      2017-04-18 CRAN (R 3.3.3)                  
 reshape2      1.4.2      2016-10-22 CRAN (R 3.3.1)                  
 rlist         0.4.6.1    2016-04-04 CRAN (R 3.3.3)                  
 rprojroot     1.2        2017-01-16 CRAN (R 3.3.2)                  
 rvest         0.3.2      2016-06-17 CRAN (R 3.3.0)                  
 scales        0.4.1      2016-11-09 CRAN (R 3.3.2)                  
 stringi       1.1.5      2017-04-07 CRAN (R 3.3.3)                  
 stringr       1.2.0      2017-02-18 CRAN (R 3.3.3)                  
 tibble      * 1.3.0      2017-04-01 CRAN (R 3.3.3)                  
 tidyr       * 0.6.1      2017-01-10 CRAN (R 3.3.2)                  
 tidyverse   * 1.1.1      2017-01-27 CRAN (R 3.3.3)                  
 TTR           0.23-1     2016-03-21 CRAN (R 3.3.3)                  
 withr         1.0.2      2016-06-20 CRAN (R 3.3.1)                  
 xml2          1.1.1      2017-01-24 CRAN (R 3.3.2)                  
 xts           0.9-7      2014-01-02 CRAN (R 3.3.2)                  
 yaml          2.1.14     2016-11-12 CRAN (R 3.3.2)                  
 zoo           1.8-0      2017-04-12 CRAN (R 3.3.3) 
jbkunst commented 7 years ago

Hi @dpprdan

Indeed, hchart and highchart are differents functions and then they have different motivations/behaviors.

About the theme: I'm agree with this can look like a bug. The issue is that hchart disable the makers (due is a line chart [and not a line-plot chart]) via plotOptions and this have priority over the theme. I know this is really subjetive, just I think it was a good default (not the perfect, but a good one)

You can force the markers using hc_plotOptions:

hc_hchart <- citytemp %>% 
  select(-new_york,-london) %>% 
  gather(city, temp, tokyo, berlin) %>%
  hchart("line", 
         hcaes(x = int, y = temp, group = city)
  )

thm <- hc_theme(
  chart = list(backgroundColor = "#eeeeee"),
  plotOptions = list(
    series = list(
      marker = list(enabled = TRUE)
      )
    )
  )

hc_hchart %>%
  hc_add_theme(thm) %>% 
  hc_plotOptions(
    series  = list(
      marker = list(enabled = TRUE)
      )
    )

image

Finally I think a good approach would be use highchart to have more control in what are you trying to do.

Regards,

dpprdan commented 7 years ago

Thanks @jbkunst! I was aware of the differences between hchart and highchart as well as hc_plotOptions() (actually I am using marker = list(enabled = TRUE) within hchart() as a work-around - "work-around" again being a matter of perspective, I guess, though not really IMHO).

Your design choices are your prerogative of course. That being said, my perspective on this is the following: No markers as a default is not a bad choice, but for consistency it should be the same (or at least be transparent) across both plotting functions. The real problem is, however, that essentially hm_add_theme() works differently (or not at all with regard to the markers and hchart for example) depending on the function that created the hc object. And that can get messy.

How about making the default theme more transparent, i.e. separate content from visualisation more, and make it possible to override it? I am pretty new to highcharts and highcharter, but as far as I can tell there is no explicit default theme at the moment? But at least implicitly you must be using some defaults (e.g. no markers with hchart). So it might be a good idea to explicitly add this as a default theme, which could then be called from within hchart() and highchart()?

Another way to look at the problem (and a bit puzzling to me), is that plotOptions in hchart() cannot be overridden, because overriding a theme seems to work fine in general? E.g. hc %>% hc_add_theme(hc_theme_google()) %>% hc_add_theme(hc_theme_ffx())

jbkunst commented 7 years ago

Thanks to you @dpprdan

I think you're right, It's better maintain the highcharts defautls. So I will delete the part wich set the markers to false in the line chart as you mention in the last part.

dpprdan commented 7 years ago

Thanks @jbkunst! Maybe you can give my idea regarding a default theme another thought as well?

Unfortunately I think I found a similar issue, though this time not directly theme-related: Please compare:

hchart(df_area, "area",
         hcaes(x = year, y = pop, group = continent)) %>% 
  hc_plotOptions(area = list(marker = list(enabled = FALSE)))

to

highchart() %>% 
  hc_add_series(df_area, "area", 
                hcaes(x = year, y = pop, group = continent)) %>% 
  hc_plotOptions(area = list(marker = list(enabled = FALSE)))

Apparently it is not possible to disable markers with hc_plotOptions on a hchart object. I suppose this problem is also related to the default options set in hchart?

jbkunst commented 7 years ago

Hi @dpprdan,

I removed the hc_plotOptions in the hchart so the next code give the same results (hchart put labels in the axis):

highchart() %>% 
  hc_xAxis(categories = citytemp$int) %>% 
  hc_add_series(name = "Berlin", data = citytemp$berlin) %>% 
  hc_add_series(name = "Tokyo", data = citytemp$tokyo) 

highchart() %>% 
  hc_xAxis(categories = citytemp$int) %>% 
  hc_add_series(citytemp2, "line",  hcaes(x = int, y = temp, group = city)) 

hchart(citytemp2, "line",  hcaes(x = int, y = temp, group = city))

I don't have the df_area, can you check if this work for that data frame too? If you can't test, can you give me some dput to make some tests?

dpprdan commented 7 years ago

I tried to install highcharter from github with devtools::install_github("jbkunst/highcharter"). library("highcharter") gives the following error:

Error in FUN(X[[i]], ...) : 
  lazy-load database 'C:/Users/daniel/Documents/R/win-library/3.4/highcharter/data/Rdata.rdb' is corrupt
In addition: Warning messages:
1: In FUN(X[[i]], ...) : restarting interrupted promise evaluation
2: In FUN(X[[i]], ...) : internal error -3 in R_decompress1

So I cannot test at the moment.

df_area is the data from the Replicating Highcharts Demos vignette:

year <- seq.int(from = 1750, to = 2050, by = 50)
Asia <- c(502, 635, 809, 947, 1402, 3634, 5268)
Africa <-  c(106, 107, 111, 133, 221, 767, 1766)
Europe <-  c(163, 203, 276, 408, 547, 729, 628) 
America <-  c(18, 31, 54, 156, 339, 818, 1201) 
Oceania <-  c(2, 2, 2, 6, 13, 30, 46)
df_area <- data.frame(year,Asia,Africa,Europe,America,Oceania) %>% gather(continent, pop, -year) 
jbkunst commented 7 years ago

@dpprdan

That's weird, Not sure what could it be. I run the devtools::install_github without problems. Not sure if you have the same result with source("https://install-github.me/jbkunst/highcharter")

(## highcharter * 0.5.0.9999 2017-04-28 Github (jbkunst/highcharter@22f0d5b) in http://rpubs.com/jbkunst/highcharter-issue-302)

dpprdan commented 7 years ago

Sorry, my fault. I had highcharter loaded in another R session, that's why the update failed.

The df_area chart works fine with regard to the markers (note that my chart example as such does not make a lot of sense, because it is not stacked - so it really is a minimal working example).

For the line charts the markers and themes work nicely. However, the two graphs differ with respect to the axis labels (which is as expected and fine) but also with respect to the x-axis tick marks (between the integer labels with highchart(), on the labels with hchart(). Do you set a default in the hchart() object for the tick marks as well? I don't have time now to figure out what setting exactly determines this (and would appreciate if you could tell me) but I remember having some problems with setting tick marks a few days back. So maybe we have the same problem as with the markers in the area plot, i.e. that it's not possible to override your default?

jbkunst commented 7 years ago

See the updated version of http://rpubs.com/jbkunst/271521. Compare:

highchart() %>% 
  hc_xAxis(categories = citytemp$int) %>%
  hc_add_series(citytemp2, "line",  hcaes(x = int, y = temp, group = city)) 

with

highchart() %>% 
  hc_xAxis(categories = citytemp$int) %>%
  hc_add_series(citytemp2, "line",  hcaes(x = as.character(int), y = temp, group = city)) 

The effect is that int is continous, and the javascript is 0-based.

dpprdan commented 7 years ago

Thanks for your explanation (and sorry for the delay)! However, I don't think that hc_add_series.vector vs. hc_add_series.data.frame nor the fact whether x is an integer or character vector is the issue here per se, but rather how hchart() handles integers differently than highchart() with respect to the x-axis markers. The following all create the same chart:

# Dataframe with x as integer
highchart() %>% 
  hc_xAxis(categories = citytemp$int) %>%
  hc_add_series(citytemp2, "line",  hcaes(x = int, y = temp, group = city))

# Dataframe with x as character
highchart() %>% 
  hc_xAxis(categories = citytemp$int) %>%
  hc_add_series(citytemp2, "line",  hcaes(x = as.character(int), y = temp, group = city)) 

# Vector with x as integer
highchart() %>% 
  hc_xAxis(categories = citytemp$int) %>% 
  hc_add_series(name = "berlin", data = citytemp$berlin) %>% 
  hc_add_series(name = "tokyo", data = citytemp$tokyo) 

# hchart with x as character
hchart(citytemp2, "line",  hcaes(x = as.character(int), y = temp, group = city))

The only different chart is this

# hchart with x as integer
hchart(citytemp2, "line",  hcaes(x = int, y = temp, group = city))

See http://rpubs.com/dpprdan/273485 for a bit more elaboration.

jbkunst commented 7 years ago

Hi @dpprdan ,

Soory for the delay!

I posted some rpubs to show why the result in every chart http://rpubs.com/jbkunst/301558 , tell me if this is clearer.

I will close the issue but you/we can reopen if is needed ;)! Thanks.