R: Building a Simple Command Line Plotting Tool/Capturing Window Close Events

R: building a simple command line plotting tool/Capturing window close events

You need something with a distinct event loop --- and the best portable solution is to rely on the (already included) tcltk package. Start with its demos.

The simplest case may be

> library(tcltk)
> tk_messageBox(message="Press a key")

which pops a box you need to acknowledge to proceed.

Leaving RScript-produced plots on screen until user interaction

This works for me on Linux:

#!/usr/bin/env Rscript

X11()
with(mtcars, plot(mpg, hp))
locator(1)

The user has to click the plot window before it disappears. I presume it would work on Windows with a call to windows() instead.

Running R Scripts with Plots

If you use the Rscript command (which is better suited for this purpose), you run it like this:

#!/usr/bin/Rscript

daq = read.table(file('mydata.dat'))
X11()
pairs(daq)

message("Press Return To Continue")
invisible(readLines("stdin", n=1))

Make sure to set the execute permission on myscript.r, then run like:

/path/to/myscript.r

or without the shebang:

Rscript /path/to/myscript.r

How to bind plot function to x11() in R?

You can define it in function like

plotInfinite <- function()
{
dev=dev.cur() # get cur device name
tt=TRUE
while(tt==TRUE)
{

mat <- matrix(sample(0:1, 50*50, replace = TRUE), 50, 50)
image(mat)
Sys.sleep(0.1)
if(dev!=dev.cur()){ tt=FALSE} #check if device changed
}
}

then

x11()
plotInfinite()

will work before closed

Octave: How to prevent plot window from closing itself?

Here is a full example, given the confusion in the comments.

Suppose you create a script called plotWithoutExiting.m, meant to be invoked directly from the linux shell, rather than from within the octave interpreter:

#!/opt/octave-4.4.1/bin/octave

h = plot(1:10, 1:10);
waitfor(h)
disp('Now that Figure Object has been destroyed I can exit')

The first line in linux corresponds to the 'shebang' syntax; this special comment tells the bash shell which interpreter to run to execute the script below. I have used the location of my octave executable here, yours may be located elsewhere; adapt accordingly.

I then change the permissions in the bash shell to make this file executable

chmod +x ./plotWithoutExiting.m

Then I can run the file by running it:

./plotWithoutExiting.m

Alternatively, you could skip the 'shebang' and executable permissions, and try to run this file by calling the octave interpreter explicitly, e.g.:

octave ./plotWithoutExiting.m

or even

octave --eval "plotWithoutExiting"

You can also add the --no-gui option to prevent the octave GUI momentarily popping up if it does.

The above script should then run, capturing the plot into a figure object handle h.
waitfor(h) then pauses program flow, until the figure object is destroyed (e.g. by closing the window manually).

In theory, if you did not care to collect figure handles, you can just use waitfor(gcf) to pause execution until the last active figure object is destroyed.

Once this has happened, the program continues normally until it exits. If you're not running the octave interpreter in interactive mode, this typically also exits the octave environment (you can prevent this by using the --persist option if this is not what you want).

Hope this helps.

Ocaml Graphics.open_graph won't work in script mode

All ressources are freed when the script terminates: memory, file descriptors, including the X window.

If you add an infinite loop, the script does not terminates, and the windows stays open.

Likewise, under the toplevel, the window stays open as long as you don't close the toplevel.

I would suggest to add two lines add the end of your script:

  • print "press enter to exit"
  • read one line from keyboard input

This way the script will not terminate until the user presses enter.

matplotlib figure does not continue program flow after close event triggered inside tk app

You can use plt.ion() to turn on Matplotlib's interactive mode, but this by itself will cause the program to continue without blocking the flow. To manually block the flow, use self.fig.canvas.start_event_loop_default() and self.fig.canvas.stop_event_loop() to pause the program flow until events are captured.

Implemented in your minimal example:

from Tkinter import *
from matplotlib import pyplot as plt

class Plotter:
def __init__(self):
plt.ion()
self.fig = plt.figure()
self.fig.canvas.mpl_connect('close_event', self.dispose)
self.fig.canvas.mpl_connect('button_press_event', self.on_mouse_click)

plt.plot(1, 2, 'r*')
plt.show()
self.fig.canvas.start_event_loop_default()
print "done with plotter"

def dispose(self, event):
self.fig.canvas.stop_event_loop()
print "disposed"

def on_mouse_click(self, event):
print 'mouse clicked!'

if __name__ == '__main__':
def pressed():
print 'button pressed'
Plotter()
print 'YAY'

root = Tk()
button = Button(root, text='Press', command=pressed)
button.pack(pady=20, padx=20)

root.mainloop()

How do I plot in real-time in a while loop using matplotlib?

Here's the working version of the code in question (requires at least version Matplotlib 1.1.0 from 2011-11-14):

import numpy as np
import matplotlib.pyplot as plt

plt.axis([0, 10, 0, 1])

for i in range(10):
y = np.random.random()
plt.scatter(i, y)
plt.pause(0.05)

plt.show()

Note the call to plt.pause(0.05), which both draws the new data and runs the GUI's event loop (allowing for mouse interaction).



Related Topics



Leave a reply



Submit