1- # ' Create a new Plotly account.
1+ # ' Create a new plotly account.
22# '
3- # ' A sign up interface to Plotly through the R Console.
3+ # ' A sign up interface to plotly through the R Console.
44# '
5- # ' @param username Desired username
6- # ' @param email Desired email
5+ # ' @param username Desired username.
6+ # ' @param email Desired email.
7+ # ' @param save If request is successful, should the username & API key be
8+ # ' automatically stored as an environment variable in a .Rprofile?
79# '
810# ' @return
911# ' \itemize{
1214# ' }
1315# ' @references https://plot.ly/rest/
1416# ' @export
15- signup <- function (username , email ) {
17+ signup <- function (username , email , save = TRUE ) {
1618 if (missing(username )) username <- verify(" username" )
1719 if (missing(email )) stop(" Must specify a valid email" )
18- base_url <- " https://plot.ly/apimkacct "
20+ # construct body of message to plotly server
1921 bod <- list (
2022 un = username ,
2123 email = email ,
2224 platform = " R" ,
2325 version = as.character(packageVersion(" plotly" ))
2426 )
27+ base_url <- file.path(get_domain(), " apimkacct" )
2528 resp <- httr :: POST(base_url , body = bod )
2629 stop_for_status(resp )
27- RJSONIO :: fromJSON(content(resp , as = " text" ))
30+ con <- RJSONIO :: fromJSON(content(resp , as = " text" ))
31+ # TODO: alter the API response messages to reflect the changes in 1.0.0
32+ if (nchar(con [[" error" ]]) > 0 ) stop(con [[" error" ]], call. = FALSE )
33+ if (nchar(con [[" message" ]]) > 0 ) message(con [[" message" ]], call. = FALSE )
34+ # store API key as an environment variable in .Rprofile
35+ if (save ) {
36+ cat_profile(" username" , con [[" un" ]])
37+ cat_profile(" apikey" , con [[" api_key" ]])
38+ }
39+ structure(con , class = " apimkacct" )
2840}
2941
30- # ' Main interface to plotly
42+ # ' Create, modify and style plotly graphs from R
3143# '
32- # ' Plotly interface object. See up-to-date documentation and examples at
44+ # ' Create, See up-to-date documentation and examples at
3345# ' https://plot.ly/API
3446# '
3547# ' @param p Either a ggplot object or a list of data/arguments to post to the
36- # ' plotly api .
48+ # ' plotly API .
3749# ' @param browse should the default web browser be prompted to open the Plotly result?
38- # ' @param ... additional arguments passed onto \code {plotly_POST}.
39- # ' @references https://plot.ly/API
50+ # ' @param ... additional arguments passed onto \link {plotly_POST}.
51+ # ' @seealso \link{signup}, \link{plotly_POST}
4052# ' @import httr RJSONIO
4153# ' @export
4254# ' @examples \dontrun{
43- # ' # You need a plotly username and API key to communicate with
44- # ' # the plotly API. These are accessed via environment variables.
55+ # ' # You need a plotly username and API key to communicate with the plotly API.
56+ # '
4557# ' # If you don't already have an API key, you can obtain one with a valid
46- # ' # username and email via the signup() function.
47- # ' usr <- 'anna.lyst'
48- # ' Sys.setenv(`plotly-username` = usr)
49- # ' resp <- signup(usr, 'anna.lyst@@plot.ly')
50- # ' Sys.setenv(`plotly-apikey` = resp[["apikey"]])
51- # ' # Note that you can set environment variables in your .Rprofile if you
52- # ' # don't want to set them everytime you start R.
58+ # ' # username and email via signup().
59+ # ' s <- signup('anna.lyst', 'anna.lyst@@plot.ly')
60+ # '
61+ # ' # If you already have a username and API key, please create the following
62+ # ' # environment variables:
63+ # ' Sys.setenv(`plotly-username` = "me")
64+ # ' Sys.setenv(`plotly-apikey` = "mykey")
65+ # ' # You can also change the default domain if you have a plotly server.
66+ # ' Sys.setenv(`plotly-domain` = "http://mydomain.com")
67+ # '
68+ # ' # If you don't want to specify these environment variables everytime you
69+ # ' # start R, you can put that code in a .Rprofile (see help(.Rprofile))
5370# '
5471# ' # Send data directly to Plotly's Javascript Graphing Library
5572# ' # https://plot.ly/javascript-graphing-library/
@@ -76,26 +93,44 @@ plotly <- function(p = last_plot(), browse = interactive(), ...) {
7693 } else if (! is.list(p )) {
7794 stop(" p must be either a ggplot object or a list" )
7895 }
79- # how to best map list to a post message?
96+ # In an effort to save some legacy users headache...
97+ # specifying username and key should still work
98+ .args <- as.list(match.call())
99+ if (" username" %in% names(.args ))
100+ Sys.setenv(`plotly-username` = args [[" username" ]])
101+ if (" key" %in% names(.args ))
102+ Sys.setenv(`plotly-apikey` = args [[" key" ]])
103+ if (! " data" %in% names(p ))
104+ stop(" p should have at least one element named 'data'" ,
105+ " (which is mapped to the args parameter in the plotly REST API)." )
80106 resp <- plotly_POST(p $ data , list (layout = p $ layout ), ... )
81107 if (browse ) browseURL(resp [[" url" ]])
82108 resp
83109}
84110
85- # ' POST messages to plotly's REST API
111+ # ' Create, modify and style plotly graphs from R
112+ # '
113+ # ' POST messages to the clientresp resource of plotly's REST API. Unlike \link{plotly},
114+ # ' this function does not support ggplot objects.
115+ # '
86116# ' @param args a list. For details see the rest API docs.
87117# ' @param kwargs a list. For details see the rest API docs.
88118# ' @param origin a character vector of length one. For details see the rest API docs.
89119# ' @param ... arguments passed along to \code{httr::POST()}
90120# ' @export
91121# ' @references https://plot.ly/rest/
122+ # ' @seealso \link{signup}, \link{plotly}
92123# ' @return An R object created by mapping the JSON content of the plotly API
93- # ' response to its R equivalent. This object has a class of "plotly_response "
124+ # ' response to its R equivalent. This object has a class of "clientresp "
94125# ' @examples
95126# '
96127# ' args <- list(c(0, 1, 2), c(3, 4, 5), c(1, 2, 3), c(6, 6, 5))
97128# ' resp <- plotly_POST(args)
98129# '
130+ # ' # translate a ggplot object with gg2list(), then upload to plotly
131+ # ' p <- gg2list(qplot(1:10))
132+ # ' resp <- plotly_POST(p$data, list(layout = p$layout), ...)
133+ # '
99134plotly_POST <- function (args , kwargs = list (filename = " plot from api" , fileopt = " new" ),
100135 origin = " plot" , ... ) {
101136 # some basic input checks
@@ -111,18 +146,18 @@ plotly_POST <- function(args, kwargs = list(filename = "plot from api", fileopt
111146 key = verify(" apikey" ),
112147 origin = origin ,
113148 platform = " R" ,
114- version = " 0.5.20 " ,
149+ version = as.character(packageVersion( " plotly " )) ,
115150 args = RJSONIO :: toJSON(args , digits = 50 , collapse = " " ),
116151 kwargs = RJSONIO :: toJSON(kwargs , digits = 50 , collapse = " " )
117152 )
118- # TODO: support different plotly domains?
119- resp <- httr :: POST(" https://plot.ly/clientresp " , body = bod , ... )
153+ base_url <- file.path(get_domain(), " clientresp " )
154+ resp <- httr :: POST(base_url , body = bod , ... )
120155 stop_for_status(resp )
121- cont <- RJSONIO :: fromJSON(content(resp , as = " text" ))
122- if (nchar(cont [[" error" ]]) > 0 ) stop(cont [[" error" ]], call. = FALSE )
123- if (nchar(cont [[" warning" ]]) > 0 ) warning(cont [[" warning" ]], call. = FALSE )
124- if (nchar(cont [[" message" ]]) > 0 ) message(cont [[" message" ]], call. = FALSE )
125- structure(cont , class = " plotly_response " )
156+ con <- RJSONIO :: fromJSON(content(resp , as = " text" ))
157+ if (nchar(con [[" error" ]]) > 0 ) stop(con [[" error" ]], call. = FALSE )
158+ if (nchar(con [[" warning" ]]) > 0 ) warning(con [[" warning" ]], call. = FALSE )
159+ if (nchar(con [[" message" ]]) > 0 ) message(con [[" message" ]], call. = FALSE )
160+ structure(con , class = " clientresp " )
126161}
127162
128163# ' Request data/layout for a particular Plotly figure
@@ -149,7 +184,7 @@ get_figure <- function(username, id) {
149184# ' @param ... placeholder.
150185# ' @export
151186# ' @references https://github.com/yihui/knitr/blob/master/vignettes/knit_print.Rmd
152- knit_print.plotly_response <- function (x , options , ... ) {
187+ knit_print.clientresp <- function (x , options , ... ) {
153188 if (! requireNamespace(" knitr" )) {
154189 warning(" Please install.packages('knitr')" )
155190 return (x )
@@ -166,7 +201,7 @@ knit_print.plotly_response <- function(x, options, ...) {
166201# ' @param height attribute of the iframe
167202# ' @export
168203embed_notebook <- function (url , width = " 100%" , height = " 525" ) {
169- if (! inherits(p , " plotly_response " )) {
204+ if (! inherits(p , " clientresp " )) {
170205 p <- plotly(p )
171206 url <- p [[" url" ]]
172207 }
@@ -182,6 +217,10 @@ embed_notebook <- function(url, width = "100%", height = "525") {
182217# Non-exported helper functions
183218# ----------------------------------------
184219
220+ get_domain <- function () {
221+ Sys.getenv(" plotly-domain" , " https://plot.ly" )
222+ }
223+
185224plotly_headers <- function () {
186225 httr :: add_headers(.headers = c(
187226 " plotly-username" = verify(" username" ),
@@ -203,6 +242,23 @@ plotly_iframe <- function(url, width, height) {
203242 url , " \" width=\" " , width , " \" frameBorder=\" 0\" ></iframe>" , sep = " " )
204243}
205244
245+ # try to write environment variables to an .Rprofile
246+ cat_profile <- function (key , value , path = " ~" ) {
247+ r_profile <- file.path(normalizePath(path , mustWork = TRUE ),
248+ " .Rprofile" )
249+ snippet <- sprintf(' \n Sys.setenv(`plotly-%s` = "%s")' , key , value )
250+ if (! file.exists(r_profile )) {
251+ message(" Creating" , r_profile )
252+ r_profile_con <- file(r_profile )
253+ }
254+ if (file.access(r_profile , 2 ) != 0 )
255+ stop(" R doesn't have permission to write to this file: " , path )
256+ if (file.access(r_profile , 4 ) != 0 )
257+ stop(" R doesn't have permission to read this file: " , path )
258+ message(" Adding plotly-" , key , " environment variable to " , r_profile )
259+ cat(snippet , file = r_profile , append = TRUE )
260+ }
261+
206262# bummer, looks like we can't use RStudio's viewer (yet) --
207263# https://github.com/rstudio/rstudioapi/issues/2#issuecomment-99250180
208264# browse_url <- function(url) {
0 commit comments