I want to automatically redirect all plotting to a file (reason: see below). Is there a non-hacky way of accomplishing that?
Lacking that, I’m actually not afraid of overriding the built-in functions, I’m that desperate. The easiest way I can think of is to hook into the fundamental plot-window creation function and calling pdf(…) and then hooking into the plot-finalising function and calling dev.off() there.
But what are these functions? Through debugging I’ve tentatively identified dev.hold and dev.flush – but is this actually true universally? Can I hook into those functions? I cannot override them with R.utils’ reassignInNamespace because they are locked, and just putting same-name functions into the global namespace doesn’t work (they’re ignored by plot).
So, why would I want to do something so horrible?
Because I’m working on a remote server and despite my best attempts, and long debugging sessions with our systems support, I cannot get X11 forwarding to work reliably. Not being able to preview a plot is making my workflow horribly inefficient. I’ve given up on trying to get X11 to work so now I’m creating PDFs in my public_html folder and just refresh the browser.
This works quite well – except that it‘s really annoying and quite time-consuming to always have to surround your plotting function calls with pdf(…) … dev.off(), especially in interactive sessions where you want to quickly create a plot while in a meeting with collaborators. In fact, it’s really annoying and they (understandably) haven’t got the patience for that.
For now I’m helping myself with the following function definition:
preview <- function (.expr, ...) {
on.exit(dev.off())
pdf(PREVIEW_FILE_NAME, ...)
eval(substitute(.expr))
}
Which is used like this:
preview(plot(1:100, rnorm(100) * 1:100))
That works a-ok. But this workflow is a real bottleneck in meetings, and I’d like to get rid of the preview call to streamline it as much as possible.
Any chance at all?
If you set options(device=FUN) then the graphics device function FUN becomes the new default graphics device that will be opened when a plot is created and device is not already opened.
So, one option would be to write a function that calls pdf or png or other graphics device with the filename and options that you want (probably onefile=FALSE in pdf), then set this function as the default in the options. You may need to use one of dev.off, plot.new, or frame to finalize the current plot (R does not finalize until you close the device or go to a new plot in case you want to add anything to the current plot).
If you will never add to a plot then you could use addTaskCallback to call dev.off automatically for you. There may be other hooks that you could use to finalize as well.
Related
I am trying to create a R package mypckg with a function createShinyApp. The latter function should create a directory structure ready to use as shiny app at some location. In this newly created shiny app, I have some variables, which should be accessed from within the shiny app, but not by the user directly (to prevent a user from accidentally overwriting them). The reason for these variables to exist (I know one should not use global variables) is that the shiny app is treating a text corpus and I want to avoid passing (and hence copying) it between the many functions because this could lead to exhaustion of the memory. Somebody using mypckg should be able to set these variables and later use createShinyApp.
My ideas so far are:
I make mypckg::createShinyApp save the protected variables in a protectedVariables.rds file and get the shinyApp to load the variables from this file into a new environment. I am not very experienced with environments so I could not get this to work properly yet because the creation of a new environment is not working upon running a shiny app so far.
I make mypckg::createShinyApp save the protected variables in a protectedVariables.rds file and get the shinyApp to load the variables from this file into the options. Thereafter I would access the variables and set the variables with options() and getOption.
What are the advantages and disadvantages of these ideas and are there yet simpler and more elegant ways of achieving my goal?
It's a little bit difficult to understand the situation without seeing a concrete example of the kind of variable and context you're using it in, but I'll try to answer.
First of all: In R, it's very very difficult to achieve 100% protection of a variable. Even in shiny, the authors of shiny tried putting up a lot of mechanisms to disallow some variables from getting overwritten by users (like the input variable for example), and while it does make it much harder, you should know that it's impossible, or at least extremely difficult, to actually block all ways of changing a variable.
With that disclaimer out of the way, I assume that you'd be happy with something that prevents people from accidentally overwriting the variable, but if they go purposely out of their way to do it, then so be it. In that case, you can certainly read the variables from an RDS file like you suggest (with the caveat that the user can of course overwrite that file). You can also use a global package-level variable -- usually talking about global variables is bad, but in the context of a package it's a very common thing to do.
For example, you can define in a globals.R file in your package:
.mypkgenv <- new.env(parent = emptyenv())
.mypkgenv$var1 <- "some variable"
.mypkgenv$var2 <- "some other variable"
And the shiny app can access these using
mypckg:::.mypkgenv$var1
This is just one way, there are other ways too
I have a Bokeh script which calls the data using a function wrapped with joblib's #memory.cache decorator. When I run the script as a python script the get_data function is fast (cached). When I call it using bokeh server --show code.py it seems like cache is lost and the function is re-evaluated, making data retrieval slow. How can I make Bokeh work nicely with Joblib?
It's hard to say for certain without being able to run an example that reproduces what you are seeing. But my guess is that it has something to do with the way the Bokeh server code runner executes the app script, on every session.
So, I can think of a few possible things to try.
First, as of 0.12.4 there's examples and guidance for embedding a Bokeh server as a library e.g. in a standalone python script, or in a Flask or Tornado app. The examples there all also use FunctionHandler which does not exec. My hunch is that this is more like the standard single process/single namespace python execution model, and will play better with your joblib decorator.
(If you try this route, and it works, please let use know somehow, it's probably worth documenting better.)
Otherwise, another option that might work better is to use lifecycle hooks to provide your wrapped function in a way that is sure to be shared across sessions. You can see this technique in the spectrogram example (c.f. the audio.py)
Finally, just some gentle advice for SO. If you can include a minimal example code, that greatly increases the odds of being able to get code back in an answer. E.g., if there was example code here that I could try to get working, then I'd be able to post a complete working code in the answer.
I'm working on some code in R that makes heavy use of the package rpostgresql. Some of the queries I'm using take quite a while to download, so I would like to periodically show a message to the users (something like "Download in progress, please be patient..") so that it is clear that the program didn't crash.
Ideally, I'd like to write the code as an all-purpose wrapper for functions so that it will give feedback to the user along the way (download in progress, time elapsed, etc.)
For example, if we have an example function:
x<-runif(10)
I would like to make a wrapper of the form
some_wrapper_function(x<-runif(10))
where some_wrapper_function gives periodic updates while the wrapped code is running.
It seems like this requires parallel coding, but with the hitch that the clusters need to talk to each other at least once.
Any thoughts? Or is there an existing function that does this?
I was wondering if it is possible to use Julia to perform computations on a webpage in an automated way.
For example suppose we have a 3x3 html form in which we input some numbers. These form a square matrix A, and we can find its eigenvalues in Julia pretty straightforward. I would like to use Julia to make the computation and then return the results.
In my understanding (which is limited in this direction) I guess the process should be something like:
collect the data entered in the form
send the data to a machine which has Julia installed
run the Julia code with the given data and store the result
send the result back to the webpage and show it.
Do you think something like this is possible? (I've seen some stuff using HttpServer which allows computation with the browser, but I'm not sure this is the right thing to use) If yes, which are the things which I need to look into? Do you have any examples of such implementations of web calculations?
If you are using or can use Node.js, you can use node-julia. It has some limitations, but should work fine for this.
Coincidentally, I was already mostly done with putting together an example that does this. A rough mockup is available here, which uses express to serve the pages and plotly to display results (among other node modules).
Another option would be to write the server itself in Julia using Mux.jl and skip server-side javascript entirely.
Yes, it can be done with HttpServer.jl
It's pretty simple - you make a small script that starts your HttpServer, which now listens to the designated port. Part of configuring the web server is that you define some handlers (functions) that are invoked when certain events take place in your app's life cycle (new request, error, etc).
Here's a very simple official example:
https://github.com/JuliaWeb/HttpServer.jl/blob/master/examples/fibonacci.jl
However, things can get complex fast:
you already need to perform 2 actions:
a. render your HTML page where you take the user input (by default)
b. render the response page as a consequence of receiving a POST request
you'll need to extract the data payload coming through the form. Data sent via GET is easy to reach, data sent via POST not so much.
if you expose this to users you need to setup some failsafe measures to respawn your server script - otherwise it might just crash and exit.
if you open your script to the world you must make sure that it's not vulnerable to attacks - you don't want to empower a hacker to execute random Julia code on your server or access your DB.
So for basic usage on a small case, yes, HttpServer.jl should be enough.
If however you expect a bigger project, you can give Genie a try (https://github.com/essenciary/Genie.jl). It's still work in progress but it handles most of the low level work allowing developers to focus on the specific app logic, rather than on the transport layer (Genie's author here, btw).
If you get stuck there's GitHub issues and a Gitter channel.
Try Escher.jl.
This enables you to build up the web page in Julia.
Does the R language have any easy way to set-up a timer function ?
By a timer function, I mean a function that sits in the background of the session and executes every so often.
Cheers!
In the tcltk2 package is the tclTaskSchedule function (and others) that could be used to do what you want. Be warned that this will usually violate the idea of functions not having side effects and you can really mess things up if the scheduled function uses any of the same objects that you are working with. It would be fine if the task just read data into a local variable and plotted the latest version (just make sure that it plots to the correct graphics device and does not mess up something else you are working on).
If you just want something to update on a regular basis you could use a repeat loop (or while) and Sys.sleep to wait the given time, then do whatever you want. You would not be able to use that R session for anything else, but you can easily have multiple R sessions running at the same time so that would not prevent you from working in another R session.
Check function ?txtProgressBar.
Regards