I'm an Octave noob but I'm trying to display a graph at the same time as an input in the terminal however the graphics only update after the input therefore I get an unloaded graph:
This is the code:
f=figure;
imshow(img);
pause(1); % FIX THIS!
in=input('Input required:', 's');
Pausing for 1 second is sketchy because it doesn't always the graph but without a pause it doesn't even enter the graphics loop. Is there someway to block until the graph is loaded before continuing? I wasn't able to find the required function in the documentation.
You can use drawnow to force the graphics to render and the event queue to be flushed.
f = figure();
imshow(img);
drawnow
in = input('Input required:', 's');
Related
My question: How to let grDevices::dev.new() work well ?
To avoid the error Error in plot.new() : figure margins too large coursing the small plot region,
I wrote the code grDevices::dev.new() in the front of plot().
However this code does not work in the first time (or after pushing the button .clean all plot button )
And this cause the errors (e.g., in the R CMD check).
Do I misunderstand the function grDevices::dev.new() ?
REF?:
R: Open new graphic device with dev.new() does not work
Answer
Using grDevices::windows() instead of grDevices::dev.new(), I overcome the issues.
Unfortunately, we cannot use grDevices::windows() , because the following error occurs in the R CMD check:
Error in grDevices::windows() :
screen devices should not be used in examples etc
Consider the following:
dev.off()
dev.cur() # null device
par("las") # opens a new device
dev.cur() # default device
My problem is identical to the one described in this question, I do not want to open a new device but the library I'm calling has unavoidable calls to par(). Also, I'd prefer a better solution than the hack described there.
My idea for solving it was the following:
change options("device") via
options(device = function(){}) # WARNING CHRASHES R WHEN CALLING PAR()
so that no new device get's opened. However as the comment indicates, this chrashes R. My question is, what should I change options("device") to such that no new device get's opened, but also R doesn't chrash when calling par.
Is it possible, to control the mouse pointer from the R console?
I have something like this in mind:
move_mouse(x_pos=100,y_pos=200) # move the mouse pointer to position (100,200)
mouse_left_button_down # simulate a press of the left button
move_mouse(x_pos=120,y_pos=250) # move mouse to select something
mouse_release_left_button # release the pressed button
In MATLAB, something like this is possible with the following code
import java.awt.Robot;
mouse = Robot;
mouse.mouseMove(0, 0);
mouse.mouseMove(100, 200);
I tried a direct conversion of the above into R that looks like this:
install.packages("rJava") # install package
library(rJava) # load package
.jinit() # this starts the JVM
jRobot <- .jnew("java/awt/Robot") # Create object of the Robot class
Once I got jRobot in R, I tried to call its metho "MouseMove(100,200)" using the two command below which both resulted in an error.
jRobot$mouseMove(10,10)
Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl, :
java.lang.NoSuchMethodException: No suitable method for the given parameters
or
.jcall(jRobot,, "mouseMove",10,10)
Error in .jcall(jRobot, , "mouseMove", 10, 10) :
method mouseMove with signature (DD)V not found
Finally I found the problem. You have to tell R that 100 is an integer, in order to pass it to java correctly.
install.packages("rJava") # install package
library(rJava) # load package
.jinit() # this starts the JVM
jRobot <- .jnew("java/awt/Robot") # Create object of the Robot class
# Let java sleep 500 millis between the simulated mouse events
.jcall(jRobot,, "setAutoDelay",as.integer(500))
# move mouse to 100,200 and select the text up to (100,300)
.jcall(jRobot,, "mouseMove",as.integer(100),as.integer(200))
.jcall(jRobot,, "mousePress",as.integer(16))
.jcall(jRobot,, "mouseMove",as.integer(100),as.integer(300))
.jcall(jRobot,, "mouseRelease",as.integer(16))
As of 2017, CRAN has a package called rMouse to handle mouse movement.
library(rMouse)
move(0,0) # move to top left corner (0,0)
move(50,30) # move to pixel x = 50, y = 30
left() # left click
right() # right click
Under the hood it still uses Java's robot.
Similarly, KeyboardSimulator package published in 2018 seems to be doing pretty much the same thing
If you are using Windows, library(KeyboardSimulator) is the easiest way.
You can use it to make a bot in R
see the example:
Move Mouse in R (RStudio)
make a bot in R (Rstudio) for social media
What operating system? In Linux, you could use xdotool and call it from the R system function.
> mousemove=function(x,y){system(paste0("xdotool mousemove ",x," ",y))}
> mousemove(0,0)
> mousemove(500,500)
Note these are screen coordinates, nothing to do with the coordinates in your R graphics window, but you weren't clear about what you wanted. You might be able to get the screen coords of your R graphics window with some other X11 utilities and position on a plot if that's what you want.
In Windows, there's probably some other mouse-tweaking program you can leech onto. IDK.
xdotool info: http://tuxradar.com/content/xdotool-script-your-mouse
further reading of that article shows how to activate particular windows and do mouse actions in them.
I've made a gui with a button, the handler of which executes a plot method of a class I made, it uses ggplot2 and grid/gridExtra in a normal R session to put together the plot. It works fine using the plot() function in console. My button/handler is below:
Plotbutton <- gbutton("Plot!", container=MainWindow,
handler=function(h,...){
plot(analysis, linesplot=svalue(linecheck), lineplot.legend=svalue(linelegcheck), baseannotate=svalue(bpcheck), bpfreq=as.numeric(svalue(bpspin)), mosaic.bars=svalue(mosaiccheck), mosaic.scale=as.numeric(svalue(mosaicspin)), combine.plots=svalue(combinecheck), condense.mosaics=svalue(condensecheck), labfontsize=as.numeric(svalue(fontspin1)), legfontsize=as.numeric(svalue(fontspin2)))
})
I'm not sure of the reason, but loading gWidgets, gWidgetstcltk, and the package required for my plot method, and then clicking the button, nothing is plotted to the R graphics environment, however in RStudio the plot panel is not updated until the GUI is exited. The graphic does appear in a window in the normal Windows RGui though.
Can anyone suggest why this is happening?
The reason why it works from the R-console and not from a function is that the R-console will invoke print() automatically if nothing else is stated. Within a function R does not do this, so if you want to print a graph, you must explicitly state print(graph). Try
print(plot(analysis, linesplot=svalue(linecheck), lineplot.legend=svalue(linelegcheck), baseannotate=svalue(bpcheck), bpfreq=as.numeric(svalue(bpspin)), mosaic.bars=svalue(mosaiccheck), mosaic.scale=as.numeric(svalue(mosaicspin)), combine.plots=svalue(combinecheck), condense.mosaics=svalue(condensecheck), labfontsize=as.numeric(svalue(fontspin1)), legfontsize=as.numeric(svalue(fontspin2)))
to simplify my daily R interactions, I'd like to set up default colors for all my plots. For example, let's say I want to have all plots made with red lines (like in gnuplot...:-) )
So far, here is a snippet of my .Rprofile
setHook(packageEvent("grDevices", "onLoad"),
function(...)
grDevices::X11.options(width = 14, height = 8, type = "Xlib", xpos = 600, ypos = 30, canvas = "grey87"))
suppressPackageStartupMessages( require(Defaults) )
suppressPackageStartupMessages( require(utils) )
suppressPackageStartupMessages( require(graphics) )
setDefaults("plot.default",frame.plot=FALSE, type='l', col=2)
What I do here is the following:
when the grDevices package is loaded (by loading the graphics package), I call the X11.options with my prefered parameters: a wider box, light gray background, xlib calls (because I'm doing distant calls, and cairo in my current environment is just too slow (another problem to solve))
Then I silently load 3 packages, Defaults, utils and graphics. The second one is needed to avoid a find function error message.
Finally, the magic function setDefaults set-up 3 parameters to the scatter plot function plot.default. The 3rd parameter col is not a parameter of plot.default but one from the par() function.
But, doing a setDefaults call with par doesn't work either.
Any solution is welcome...
You can use the "plot.new" hook to set default par values each time a new graphics frame is opened. (The hook's workings are documented in ?plot.new and ?setHook)
In your case, just add this line to your .Rprofile:
setHook("plot.new", function() par(col = "red"))
The parameters such as color are set on a per device basis, so when you close one device and create a new one all the parameters are set back to their default values. To do this I would create your own device function that opens the device then sets the parameters, something like:
mydev.new <- function(...) {
dev.new(...)
par(col='red')
}
You could obviously replace dev.new with x11 or something else, but this is probably the most portable. Now you can open a new device using mydev.new and the default color will be set to red.
Further if you run the command
options(device=mydev.new)
Then when you don't have a graphics device open and you run a plotting command, your function will be the one run to open a new plotting device and so the default will be red in that case as well. You could expand the mydev.new function (or whatever you want to call it) to set other options, take arguments, etc. for different cases you may want to work with.