bugGNU Octave - Bugs: bug #48718, plot command clobbers axis...

 
 

bug #48718: plot command clobbers axis "position" property with "hold on"

Submitter:  Doug Stewart <dastew>
Submitted:  Sun 07 Aug 2016 09:42:31 PM UTC
   
 
Category:  Plotting with OpenGL Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  None
Originator Name:  Doug Stewart Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Thu 18 Oct 2018 03:20:06 AM UTC, comment #14: 

I pushed the last changeset here: https://hg.savannah.gnu.org/hgweb/octave/rev/91711db98d8a.

Marking as fixed and closing report.

Rik <rik5>
Group administrator
Wed 17 Oct 2018 09:02:39 PM UTC, comment #13: 

the end of the previous post:


octave:1> close all
octave:2> ylabel "y-axis";
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
octave:3> hold on
octave:4> pos1 = get (gca, "position")
pos1 =

   0.13000   0.11000   0.77500   0.81500

octave:5> plot((1:2), (1:2)*1e-4)
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
sync_position skipped
sync_position skipped
sync_position skipped
update_axes_layout OK
sync_position skipped
sync_position skipped
sync_position skipped
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
sync_position done
update_axes_layout OK
update_axes_layout OK
sync_position done
update_axes_layout OK
update_axes_layout OK


(file #45229)

Pantxo Diribarne <pantxo>
Group Member
Wed 17 Oct 2018 09:00:44 PM UTC, comment #12: 

Looks like I have found a much more economic solution: skipping sync_positions calls that are triggered during update_axes_layout. See attached patch.

The advantage is that sync_position can no more use erroneous data to compute the position, but it looks like recursive calls to update_axes_layout are also eliminated:


octave:1> close all
octave:2> ylabel "y-axis";
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
octave:3> hold on
octave:4> pos1 = get (gca, "position")
pos1 =

   0.13000   0.11000   0.77500   0.81500

octave:5> plot((1:2), (1:2)*1e-4)
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
sync_position skipped
sync_position skipped
sync_position skipped
update_axes_layout OK
sync_position skipped
sync_position skipped
sync_position skipped
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
update_axes_layout OK
sync_position done
update_axes_layout OK
update_axes_layout OK
sync_position done
update_axes_layout OK
update_axes_layout OK
-verabtim-

(file #45228)

Pantxo Diribarne <pantxo>
Group Member
Wed 17 Oct 2018 08:08:05 PM UTC, comment #11: 

I attached an updated patch, the call to update_ticklength is now in calc_tightbox which is non const and eventually called less often than get_extent.

To give you an idea of the number of skipped reentrant calls to update_axes_layout and also of the number of additional calls to update_ticklength, I have put a few printf and ran code from comment #5:


octave:1> close all
octave:2> ylabel "y-axis";
update_axes_layout #1 OK
update_axes_layout #2 OK
** Additionnal call to update_ticklength **
update_axes_layout #3 OK
update_axes_layout #4 OK
update_axes_layout #5 OK
** Additionnal call to update_ticklength **
update_axes_layout #6 OK
update_axes_layout #7 OK
update_axes_layout #8 OK
** Additionnal call to update_ticklength **
update_axes_layout #9 OK
update_axes_layout #10 OK
octave:3> hold on
octave:4> pos1 = get (gca, "position")
pos1 =

   0.13000   0.11000   0.77500   0.81500

octave:5> plot((1:2), (1:2)*1e-4)
update_axes_layout #11 OK
update_axes_layout #12 OK
update_axes_layout #13 OK
update_axes_layout #14 OK
update_axes_layout #15 skipped
** Additionnal call to update_ticklength **
update_axes_layout #16 skipped
update_axes_layout #17 skipped
update_axes_layout #18 skipped
** Additionnal call to update_ticklength **
update_axes_layout #19 skipped
update_axes_layout #20 skipped
update_axes_layout #21 skipped
** Additionnal call to update_ticklength **
update_axes_layout #22 skipped
update_axes_layout #23 skipped
update_axes_layout #24 OK
update_axes_layout #25 skipped
** Additionnal call to update_ticklength **
update_axes_layout #26 skipped
update_axes_layout #27 skipped
update_axes_layout #28 skipped
** Additionnal call to update_ticklength **
update_axes_layout #29 skipped
update_axes_layout #30 skipped
update_axes_layout #31 skipped
** Additionnal call to update_ticklength **
update_axes_layout #32 skipped
update_axes_layout #33 skipped
update_axes_layout #34 OK




(file #45226)

Pantxo Diribarne <pantxo>
Group Member
Wed 17 Oct 2018 03:19:06 PM UTC, comment #10: 

@Pantxo: Okay, sounds like a good plan.

Rik <rik5>
Group administrator
Wed 17 Oct 2018 07:33:19 AM UTC, comment #9: 

@Rik: Good point. Basically the problem is that the ylabel object coordinates, which are expressed in "data" units, need to be updated when axes limits change. So far so good, "lets add an updater for xyzlim that will call update_axes_layout" I said to my self ... but that is already the case. The problem seams to be that the chain of updates provokes reentrant calls to "update_axes_layout" (which is where "update_ticklength" ends up being called) but there is a static variable that specifically prevents recursion in this function.

It took be much time to arrive to this simple conclusion, now understanding the exact chain of events and eventually reorganizing it to not fail (and to not call "update_axes_layout" so often, sometimes to no avail) is a much harder task.
I admit it looks strange to have a non const get_xxx method, I also admit forcing the position update in some unexpected spot for solving one particular case is not elegant, but doing it properly will involve much more work.

Since this bug is ugly and triggered so easily I propose to look again where I can put this "update_ticklength" call, preferably in a non const method, and accompany it with a FIXME that references this bug report. From a performance perspective, I don't expect it to be a big deal.

Pantxo Diribarne <pantxo>
Group Member
Wed 17 Oct 2018 04:21:07 AM UTC, comment #8: 

The patch works just fine.  But is it the right place to fix the issue?  Why should get_extent not be const?  It seems like perhaps the problem lies elsewhere in that update_ticklength should be getting called after ylabel changes things.  If this isn't right, or is too much trouble, then the patch can be checked in as is.  Since get_extent is called several times in graphics.cc, does this decrease performance?

Rik <rik5>
Group administrator
Mon 15 Oct 2018 03:18:50 PM UTC, comment #7: 

The problem seams to be that the ylabel position (which is expressed relative to the axes data) is not refreshed properly before computing the axe extent. The following simple change fixes the issue for me.

(file #45200)

Pantxo Diribarne <pantxo>
Group Member
Fri 11 Aug 2017 12:44:28 PM UTC, comment #6: 

This bug is still present.
Hg id =92a3b165689e

Doug Stewart <dastew>
Sun 19 Mar 2017 11:01:34 PM UTC, comment #5: 

This is really odd, and ugly.  Something is clobbering the "position" property of the axes.

Try this test code:


close all
ylabel "y-axis";
hold on
pos1 = get (gca, "position")
plot((1:2), (1:2)*1e-4)
pos2 = get (gca, "position")
set (gca, "position", pos1);


When I run it I get the following.


pos1 =

   0.13000   0.11000   0.77500   0.81500

pos2 =

   1.3000e-01   3.5531e+12   7.7500e-01  -7.1061e+12


Not only is the y-position of the axes a huge 3.5e12, but the height is a negative number.  That is just impossible.

The plot looks normal to me after I restore the previously saved position property with the final set command.


Rik <rik5>
Group administrator
Fri 24 Feb 2017 12:17:06 PM UTC, comment #4: 

this is still not fixed !!!

Doug Stewart <dastew>
Mon 08 Aug 2016 04:47:37 AM UTC, comment #3: 

This will make an empty plot for me:


octave:1> ylabel "y"; hold on
octave:2> plot((1:2), (1:2)*1e-4)


Dmitri.

Dmitri A. Sergatskov <dasergatskov>
Mon 08 Aug 2016 04:40:12 AM UTC, comment #2: 

I can reproduce it with a single plot:

octave:1> xlabel("hi")
octave:2> hold on
octave:3> plot((1:2)*1e-4, 1:2)


It looks like the issue with OpenGL using floats.

Dmitri.

Dmitri A. Sergatskov <dasergatskov>
Mon 08 Aug 2016 04:12:11 AM UTC, comment #1: 

Running this script in windows, I do not get a blank plot, but the attached wrong plot.

Running it with gnuplot toolkit, the figure looks OK,
but the x-labels are overlapping.
If I print the figure, the x-labels are OK (see the attached a_gnuplot.png).

I have changed the title to "wrong plot...", the OS to "any", and the category to "Plotting with OpenGL".


Avinoam Kalma <avinoam>
Group Member
Sun 07 Aug 2016 09:42:31 PM UTC, original submission:  

ubuntu 16.04 and dev. and default qt graphics.

There are three things that all must happen to show this bug.
1) must have at least 2 subplots.
2) the x data range must be < 1e-3
3) the xlabel must be before the lines are drawn

With these 3 conditions then the plot is wrong( blank)

You can use this code to explore the 3 conditions.



x=[0:4] * 1e-4;
for k=1:2
subplot(2,1 ,k)
xlabel("hi")
hold on
plot(x,rand(5,3))
hold off
#xlabel("KK")
endfor


Doug Stewart <dastew>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #45200:  hold_and_labels.patch added by pantxo (2KiB - text/x-patch)
file #38144:  a.png added by avinoam (7KiB - image/png)
file #38145:  a_gnuplot.png added by avinoam (34KiB - image/png)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by pantxo (Updated the item)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by dasergatskov (Posted a comment)
  • -email is unavailable- added by avinoam (Updated the item)
  • -email is unavailable- added by dastew (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 15 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2018-10-18 rik5 StatusPatch Reviewed Fixed
        Open/ClosedOpen Closed
    2018-10-17 pantxo Attached File- Added avoid_recurse_sync_position.patch, #45229
    2018-10-17 pantxo Attached File- Added avoid_recurse_sync_position.patch, #45228
    2018-10-17 pantxo Attached File- Added update_labels_position.patch, #45226
    2018-10-17 rik5 StatusPatch Submitted Patch Reviewed
    2018-10-15 pantxo Attached File- Added hold_and_labels.patch, #45200
        StatusConfirmed Patch Submitted
    2017-03-19 rik5 StatusNone Confirmed
        SummaryWrong plot under some conditions plot command clobbers axis "position" property with "hold on"
    2016-08-08 avinoam Attached File- Added a.png, #38144
        Attached File- Added a_gnuplot.png, #38145
        CategoryPlotting Plotting with OpenGL
        Operating SystemGNU/Linux Any
        SummaryBlank plot under some conditions Wrong plot under some conditions

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code