bugGNU Octave - Bugs: bug #36679, Timing error for multiple plots

 
 

bug #36679: Timing error for multiple plots

Submitted by:  Michael Godfrey <godfrey>
Submitted on:  Tue 19 Jun 2012 01:17:10 AM UTC  
 
Category: Plotting with OpenGLSeverity: 3 - Normal
Priority: 5 - NormalItem Group: Incorrect Result
Status: NoneAssigned to: None
Originator Name: Michael GodfreyOpen/Closed: Open
Release: devOperating System: GNU/Linux

Add a New Comment (Rich MarkupRich Markup):
   

You are not logged in

Please log in, so followups can be emailed to you.

 

(Jump to the original submission Jump to the original submission)

Mon 02 Jul 2012 08:52:41 PM UTC, comment #14:

Well, I was too optimistic. I just tried another
similar plotting case, and have found that only
the unconditional drawnow() at the start of newplot()
works correctly.

So, instead of the proposed change to line 58 of
newplot() can we go with the insertion of drawnow();
after line 28? Does this mean that the __request
at line 58 may still be needed? Or should it be deleted
or changed to drawnow()?

Michael Godfrey <godfrey>
Mon 02 Jul 2012 08:39:21 PM UTC, comment #13:

I tried replacing the _request_drawnow_ with
drawnow();
Since the __request is within a case statement
this results in many fewer calls to drawnow
than having the drawnow() unconditionally called.
(In my cae there are 11 calls to newplot() for
each pass through the top loop, but ony one
is a case "replace" which leads to drawnow()
being called.) However, the good news is that
this fixes the problem. This also narrows the
scope for searching for the real cause of this
error.

So, I am definitely in favor of changing line 58 of
newplot() to drawnow();

I did previously try putting a drawnow() at line
412 of print.m but it did not help. Also, tried
the usual pause()'s.

So, Rik, could you make the patch to newplot()?
This may not be a complete solution, but it will help
a lot. And, it is separate from other problems with
getting print() to be better behaved.

Michael Godfrey <godfrey>
Mon 02 Jul 2012 04:08:10 PM UTC, comment #12:

Responding in the order of the original comments:

1) reset () is broken for plots and doesn't actually reset all of the properties to their defaults. There is already a bug report filed on that. However, I have never had a problem if I actually use 'close all' to shut down everything associated with the plotting engine.

2) newplot is called by everything but line(); so there is a possible bypass route around any drawnow put in newplot()

3) I agree that we still don't have a clear understanding of this bug. If it is related to callbacks, then putting drawnow() in the appropriate location should fix it.

4) In newplot there is a call to _request_drawnow_ which sets a variable that asks Octave to run drawnow the next time the user hits a prompt. This is only a request, and it is possible that when running from a script several plots are done in a row before the user is returned to a prompt and drawnow is executed. What happens if you replace line 58 of newplot.m with a straight call to drawnow () rather than to _request_drawnow_?

5) You may have done this in previous tests, but what happens if you put a drawnow () call just ahead of line 412 in print.m? There is already a call to drawnow () at the head of print.m but it is before a lot of properties have been altered. I'm thinking a second call might be necessary.

Rik <rik5>
Project Administrator
Sun 01 Jul 2012 09:06:00 PM UTC, comment #11:

And, as a final test for now, I deleted
the drawnow() in newplot() and the
plot in my code fails again. No other
changes.

For anyone who understands this code:
doews drawnow in newplot do any harm?
Is this a reasonable fix?

I still feel that the "real" problem has
not been identified.

Michael Godfrey <godfrey>
Sun 01 Jul 2012 08:56:39 PM UTC, comment #10:

Another experiment:

1. I removed all the pause() and drawnow()
calls in my plotting code.
2. I inserted a drawnow() at the beginning
of newplot().

newplot appears to be called by all the user
plotting commands, so I thought this would be
a useful place to force drawnow for each plot
command.

Right now it seems to work.

Michael Godfrey <godfrey>
Sun 01 Jul 2012 07:56:02 PM UTC, comment #9:

I tried the for loop, but it did no good.
Then I just put back the
drawnow();
pause(3);
in the "middle" of the sequence of plots with hold on.
This "fixed" it.
Then I removed the loop (actually I tried loop; pause(3); loop)
and it still worked.

So, this suggests that doing too many plot commands with
hold on and no drawnow(); is important.

Another factor is that this plotting script has a
for fig = 1:3
close all
clear -x fig
hold off %
figure(fig) %
hold on %
.............
as the start of its outer loop.
The first time through the loop has, as far as I can
remember, always worked. Sometimes the second time fails,
but most often it is the last time through that fails.
This means that the sequence following the for statement
is not reinitializing plotting. Some state must be
"leftover" somewhere.

Michael Godfrey <godfrey>
Sun 01 Jul 2012 03:33:14 PM UTC, comment #8:

I'm still interesting in confirming that our thinking about the problem is correct. Our assumption is that if the callbacks had enough time to run, then everything would be okay.

I should have remembered that pause() ties everything up. But what about using a busy loop as a delay element for testing?

The following code takes about 0.9 seconds on my computer.

You could always use tic/toc and adjust the loop range to get a delay appropriate for your computer.

If this delay is inserted before line 412 of print.m do the problems go away?

Rik <rik5>
Project Administrator
Sat 30 Jun 2012 01:36:22 PM UTC, comment #7:

Also, I thought that additional drawnow() commands
in print.m might help, but they did not.

Michael Godfrey <godfrey>
Fri 29 Jun 2012 06:53:38 PM UTC, comment #6:

Rik,

Thanks for thinking about this. I have tried quite
a number of experiments using pause(). Including placing
a pause() at line 412 as you suggested. Somewhat to
my surprise this pause() and pause() immediately
before the print() in my code does not in general help.

What seems to be mor reliable is to place pause(n)
statements between the sequences of plot() commands.
It appears to be the case that if a long sequence of plot()
commands with hold on are given, the system gets into
a state such that it never reaches a correct state for
printing.
(Even though the dispalyed plot is correct!)

A key part of this problem, I think, is the current
requirement that the figure has to be rendered in order
for print() to work. It is obvious that Matlab has found
a way around this even though they appear to use OpenGL.
In Matlab you can move the figure to anywhere on the screen
and then do a print(). The figure does not move as a result.
In Octave, if you move the figure, it then is moved back to
an "original" position when print() is done. It is also
resized.

Also, John pointed out that pause() waiting at the command
line prevents callbacks from being processed. Thus, there
does not seem to be a reliable way of "waiting" without
inhibiting actions that you are waiting for,

My lack of detailed knowledge of OpenGL and FLTK does not
help in this case. Sorry.

Michael Godfrey <godfrey>
Fri 29 Jun 2012 06:31:55 PM UTC, comment #5:

Following your logic, I wonder if the most of the calls which alter figure attributes return before the effects of those changes have been propagated.

It makes some sense. Changing the figure position property properly causes some listeners to fire. If the print script continues before the listeners have had a chance to execute themselves then you might have results which are out of sync with what should be appearing on the screen.

Just for the sake of testing, you might want to add a pause() statement just before the actual call to print the figure which is at line 412 of print.m.

If a delay works there, then we can think of how to approach this.

Rik <rik5>
Project Administrator
Thu 21 Jun 2012 07:31:16 PM UTC, comment #4:

A bit more information: the obvious
purpose of the
set (opts.figure, "position", fpos);
is to make the figure BB be invariant
to the size and position of the figure on
the screen. This is consistent with the
Matlab way. For the same plot in Matlab
and Octave (using set above) I got:
Matlab:
t1.ps:9:%%BoundingBox: (atend)
t1.ps:162:%%PageBoundingBox: 73 215 552 589
t1.ps:347:%%BoundingBox: 73 215 552 589
t2.ps:9:%%BoundingBox: (atend)
t2.ps:162:%%PageBoundingBox: 73 215 552 589
t2.ps:347:%%BoundingBox: 73 215 552 589

Octave:
t1.ps:3:%%BoundingBox: 70 232 548 602
t1.ps:4:%%HiResBoundingBox: 70.900000 232.300000 547.100000 601.600000
t1.ps:52:%%PageBoundingBox: 0 0 612 792
t2.ps:3:%%BoundingBox: 70 232 548 602
t2.ps:4:%%HiResBoundingBox: 70.900000 232.300000 547.100000 601.600000
t2.ps:52:%%PageBoundingBox: 0 0 612 792

Pretty close, but not the same,

In any case this means that the "set" of fpos to opts.canvas_size
is needed. So, it just needs to work all the time and
if possible stop moving the figure around.

Anyone have any ideas of how to do this?

Michael Godfrey <godfrey>
Thu 21 Jun 2012 07:00:44 PM UTC, comment #3:

I have located the code in print.m which
seems to cause the BB change. The line is
at 323:

set (opts.figure, "position", fpos);

If this line is commented out the BoundingBox
for all plots in the loop is the same without
any pause() commands. However, it is not the
size that was previously "correct." It is
the samller size which occurs after a number of
plots without any pauses.

It is also true that this command causes the figure on the
screen to move up (and I assume) expand. Having the
figure jump on the screen during print() is not too
good. The original position and size is restored
when print() is done.

So, the reason for the BB size change is that the
set command above does not always take effect before
print actually generates to output file.

Two things need fixing:

1. Figure out how to make the set command take effect
before print generates the file.

2. Figure out how to make the set NOT move the figure
on the screen. At least, not cause the base of the
figure to jump up. The figure may have to change
since its size presumably must change to get the
BoundingBox right.

It would be great if anyone who is familiar with this
code could comment on possible fixes.

This has actually been a long-standing problem, but
it would be very heplful to get it resolved. In my
experience, the problem happened much more when using
a "slow" X11 connection (as in remotely over DSL). But,
now I am doing these tests on a local machine (Fedora 17).

Michael Godfrey <godfrey>
Tue 19 Jun 2012 03:26:20 PM UTC, comment #2:

One additional fact: I tried replacing
the pause(6), placed immediately before
the print command, with:
drawnow();
pause(3);

For the cases that worked without the pause
the figure with all the data is shown during the
pause. For the case that failed, only a blank
figure is shown until after the pause when
the print ... is running.

So, it appears that drawnow() not working
and print failing to produce the correct BB
are related.

Michael Godfrey <godfrey>
Tue 19 Jun 2012 01:50:19 PM UTC, comment #1:

I was unclear about one point below: the pause(6)
needs to be placed within the sequence:

hold on
... some plot calls
hold off

Each figure is made up of quite a few plot calls which
add data curves to the figure.

Michael Godfrey <godfrey>
Tue 19 Jun 2012 01:17:10 AM UTC, original submission:

I am sorry to say that this problem is hard to document by an
example since it depends on timing of a sequence of plots.
I am attaching the zip of 2 plots which show the problem.
These 2 plots have the same BoundingBox if produced with a
pause(6) between the sets of plot calls which create them.
If the pause(6) is commented out the second plot has the
samller BoundingBox as shown by:
[pbdsl3:n1] grep Bound *.ps
vds1.ps:3:%%BoundingBox: 43 219 587 617
vds1.ps:4:%%HiResBoundingBox: 43.600000 219.400000 587.000000 616.900000
vds1.ps:52:%%PageBoundingBox: 0 0 612 792
vds2.ps:3:%%BoundingBox: 41 213 573 569
vds2.ps:4:%%HiResBoundingBox: 41.500000 213.700000 572.500000 568.800000
vds2.ps:52:%%PageBoundingBox: 0 0 612 792

At first I thought that the change in BB size was due to some
environment change between the plots since they allways had the
correct BB if produced separately. But, I cleaned up the code
and inserted additional cleanup as:
for fig = 1:2
close all
clear -x fig
hold off %
figure(fig) % This set of three commands MUST be set for correct BB
hold on %

This seemed to "work" in some cases but eventually failed
depending on, I think, the complexity of the plots.

I seems odd that only the BB appears to be affected.

If anyone has any tests that they would like me to run
I will try to help. I tried to put together a simple example,
but -- of course -- that did not fail.

The Linux system is Fedora 17 x86_64. And, I just recompiled
the devel system with the latest patches including the
plotyy.m fix.

Michael Godfrey <godfrey>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

Attached Files
file #26057:  plots.zip added by godfrey (44kB - application/zip)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by rik5 (Posted a comment)
  • -unavailable- added by godfrey (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follows 1 latest change.

    Date Changed By Updated Field Previous Value => Replaced By
    Tue 19 Jun 2012 01:17:10 AM UTCgodfreyAttached File-=>Added plots.zip, #26057

    Back to the top


    Powered by Savane 3.1-cleanup