Skip to content

WISH: Serialization / saving of plotly_hash objects #639

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
HenrikBengtsson opened this issue Jul 1, 2016 · 5 comments
Closed

WISH: Serialization / saving of plotly_hash objects #639

HenrikBengtsson opened this issue Jul 1, 2016 · 5 comments

Comments

@HenrikBengtsson
Copy link

HenrikBengtsson commented Jul 1, 2016

Due to the dependency of the session-specific plotly:::plotlyEnv environment, it is not possible to serialize a plotly_hash object and reuse it in a separate R session.

Here's a reproducible example. First,

> library("plotly")
> p <- plot_ly(economics, x = date, y = unemploy / pop)
> saveRDS(p, "plotly.rds")
> quit("no")

Second, in a separate R session:

> library("plotly")
[...]
> p <- readRDS(p, "plotly.rds")
Error in readRDS(p, "plotly.rds") : object 'p' not found
> p <- readRDS("plotly.rds")
> p
Error in get(hash, envir = plotlyEnv) : 
  object 'c797a49c4fa827252c5c34c307a75ed5#0' not found

The error is not surprising in the sense that the object depends on an object that was only available in the plotly:::plotlyEnv environment of the first R session.

Workaround

One can carry over the missing information automatically, but inefficiently if plotlyEnv contains lots of other objects, by attaching the plotlyEnv to the object as an attribute. Proof of concept:

> library("plotly")
> p <- plot_ly(economics, x = date, y = unemploy / pop)
> attr(p, "envir") <- plotly:::plotlyEnv
> saveRDS(p, "plotly.rds")
> quit("no")

and in a new R session:

> library("plotly")
> p <- readRDS("plotly.rds")
> env <- attr(p, "envir")
> for (name in ls(envir=env)) assign(name, get(name, envir=env),  envir=plotly:::plotlyEnv)
> p

where printing p opens up a temporary HTML file in the browser, i.e. it works.

Suggestion / Question

With the disclaimer that I'm a first timer to plotly and have no clue about its design, would it be possible / make sense to tie this environment to the object itself rather than having it as global environment?

Background

I'm testing various graphing environments with my future package to see which can be evaluated remotely / in a separate R session (think parallel / distributed processing). For instance, with ggplot2, profvis, lattice and rebokeh, one can do things such as:

> library("future")
> plan(remote, workers = "localhost")  # or workers = "remote.server.org"
> library("rbokeh")
> p %<-% {
+    figure() %>% ly_points(Sepal.Length, Sepal.Width, data = iris, color = Species, glyph = Species,hover = list(Sepal.Length, Sepal.Width))
+ }
> p

and this evaluates the graphing expression remotely butrenders it's in my local session.

However, when I try with plotly, I get (for the above reasons):

> library("future")
> plan(remote, workers = "localhost")  # or workers = "remote.server.org"
> library("plotly")
> p %<-% plot_ly(economics, x = date, y = unemploy / pop)
> p
Error in get(hash, envir = plotlyEnv) :
  object 'b3ca8b4c478cfd96589d869a79bf27b0#1' not found

If that information in the plotlyEnv environment, or the environment itself, would be tied to the plotly_hash object I'm pretty sure local plotting of remote plotly objects would work too.

PS. Thanks for a great useR2016 talk.

@cpsievert
Copy link
Collaborator

Thanks @HenrikBengtsson! I'm hoping by the end of next week, #628 will be merged, which should solve this issue.

@HenrikBengtsson
Copy link
Author

Sounds great - looking forward to it.

@ijlyttle
Copy link

ijlyttle commented Jul 12, 2016

Hey - just stumbled across this trying to figure out something else about plotly (Carson - I might try to get ahold of you at some point - just as a warning :)).

FWIW, I can propose another workaround (maybe). I remember Hadley talking about how closures are useful because they enclose the environment in which they were created. ref

With that in mind, I tried this out and it seems to work:

library("plotly")

p <- function(){
  plot_ly(economics, x = date, y = unemploy / pop)
} 

saveRDS(p, "plotly.rds")
quit("no")
library("plotly")
p <- readRDS("plotly.rds")
p()

Of course, this may not in fact be useful to what you're trying to do, but hopefully it can be at least entertaining.

@HenrikBengtsson
Copy link
Author

I've just tried with the fix/nse branch;

source("http://callr.org/install#ropensci/plotly@fix/nse")

I'm happy to confirm that with this version installed, one can now do:

> library("future")
> plan(remote, workers = "localhost")

> library('plotly')
> p %<-% plot_ly(z = volcano, type = "surface")
> p

where the plotly object is created in the "remote" R process and then rendered in the local web browser when printing p.

This also means one should be able to save it to disk, e.g.

> saveRDS(p, "volcano.plotly.rds")
> quit("no")

and then in a fresh R session:

$ R --vanilla --quiet
> p <- readRDS("volcano.plotly.rds")
> p

Indeed; the plotly object is rerendered.

Looking forward to next release.

@cpsievert
Copy link
Collaborator

Closed via d2bf2a1. Let us know if you're still having problems, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants