13

From the octave CLI or octave GUI, if I run

plot([1,2,3],[1,4,9])

it will display a plot window that I can look at and interact with. If however I create file myPlot.m with the same command as content

plot([1,2,3],[1,4,9])

and that I run it with

octave myPlot.m

then I can briefly see the plot window appear for a fraction of a second and immediatly close itself. How can I prevent this window from closing itself?

Octave 4.2.2 Ubuntu 18.04

Gael Lorieul
  • 3,006
  • 4
  • 25
  • 50
  • Possible duplicate of [Getting octave to plot when invoking a function from the command line](https://stackoverflow.com/questions/6843014/getting-octave-to-plot-when-invoking-a-function-from-the-command-line) – Cris Luengo Sep 29 '18 at 15:11
  • My question is not about how to disable interactive mode, it is about having a plot window that does not close itself. That being said, some of the answers might be helpful to me. – Gael Lorieul Sep 29 '18 at 15:54
  • Yes, the duplicate points to answers that answer your question, not necessarily to an identical question. The duplicates help people find the right answers without us having to type the same answers multiple times. :) – Cris Luengo Sep 29 '18 at 16:08
  • 1
    yes the answer is to use the `waitfor` command after your plot. This waits until the plot is closed, and if it's the last command in your script, it will exit octave appropriately. – Tasos Papastylianou Oct 01 '18 at 16:35
  • @TasosPapastylianou thanks for the tip! It was also mentioned in the duplicate question, but unfortunately the person who gave the [answer](https://stackoverflow.com/a/42174553/3492512) did not show a full script example i.e. in `waitfor(h)` where do you get `h` from? – Gael Lorieul Oct 09 '18 at 03:52

2 Answers2

12

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.

Tasos Papastylianou
  • 21,371
  • 2
  • 28
  • 57
  • It's a bit weird: the window opens and does not shut itself automatically, so the `waitfor(h)` instruction works in that sense. However, the `(1:10,1:10)` line does not show until I close the window! Before that I see a pair of axis and a blank plot! Same behavior with `waitfor(gcf)`. – Gael Lorieul Oct 10 '18 at 17:09
  • @GaelLorieul IMPOSSIBRU! Perhaps it's a bug of the older version you're using? It doesn't make sense otherwise, since I do not create axes separately in my example. Also, what operating system are you using? – Tasos Papastylianou Oct 10 '18 at 17:34
  • For a figure with hold on, I had to add a pause(1) above the waitfor statement. Without the pause, the legend was not shown. It seems that the block started before the legend was actually drawn. – guru May 01 '19 at 17:23
  • @guru this sounds more like a bug (possibly a regression bug if you're on the latest octave). I'd encourage you to report it on the octave bug tracker. – Tasos Papastylianou May 02 '19 at 14:18
  • update: if you're getting the same "blank plot" issue as @GaelLorieul above, try using the `drawnow` command just before the `waitfor` one. This forces the plot to be drawn right there and then, rather than wait for a "good opportunity" to flush the contents onto the plot. It appears that octave does not necessarily consider a `waitfor` event to be such an opportunity ... and presumably then freezes any inner workings that would create such an opportunity further down the line. – Tasos Papastylianou Jul 07 '21 at 10:38
7

Run @terminal as (need to exit octave later)

octave --persist myscript.m

or append

waitfor(gcf)

at the end of script to prevent plot from closing

Riyas Jaleel
  • 71
  • 1
  • 2