bugGNU Octave - Bugs: bug #39243, patch {x,y,z,c}data properties are...

 
 

bug #39243: patch {x,y,z,c}data properties are not independent

Submitter:  Ben Abbott <bpabbott>
Submitted:  Thu 13 Jun 2013 02:40:49 AM UTC
   
 
Category:  Plotting with OpenGL Severity:  2 - Minor
Priority:  3 - Low Item Group:  Matlab Compatibility
Status:  Fixed Assigned to:  None
Originator Name:  Ben Abbott 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

Tue 30 Nov 2021 05:22:46 PM UTC, comment #21: 

also appending the opengl warning repetition details to bug #61088

Nicholas Jankowski <nrjank>
Group Member
Tue 30 Nov 2021 04:26:32 PM UTC, comment #20: 

discovered this behavior applies inconsistently with other drawing objects, and matlab's behavior isn't consistent either.  created bug #61591 focused on set inconsistencies, rather than steering this old report in an different direction from where it started.

reverting my rename from the other day, and closing as fixed.

Nicholas Jankowski <nrjank>
Group Member
Tue 30 Nov 2021 12:23:04 AM UTC, comment #19: 

I've seen a number of cases where Matlab allows you to change/set a property after the fact that you wouldn't be able to set initially. In some cases it only catches incompatibilities later (in this case, maybe something like a call to 'draw').

In Octave, to trim both xdata and ydata via set, you have to do them one at a time, and you get the intermediate warning.  In Matlab, if you trim xdata or ydata, it automatically trims the other to match:

octave:

>> xdata = cosd (0:60:360);
>> ydata = sind (0:60:360);
>> h = patch (xdata, ydata, 'b', 'marker', 's'); %% draws hexagon
>> get(h, 'xdata'),get(h, 'ydata')
ans =
   1.0000
   0.5000
  -0.5000
  -1.0000
  -0.5000
   0.5000
   1.0000

ans =
        0
   0.8660
   0.8660
        0
  -0.8660
  -0.8660
        0

>> set (h, 'xdata', xdata(1:end-3));
>> warning: opengl_renderer: x/y/zdata must have the same dimensions.  Not rendering.
get(h, 'xdata'),get(h, 'ydata')
ans =
   1.0000   0.5000  -0.5000  -1.0000

ans =
        0
   0.8660
   0.8660
        0
  -0.8660
  -0.8660
        0

>> set (h, 'ydata', ydata(1:end-3));
>> get(h, 'xdata'),get(h, 'ydata')
ans =
   1.0000   0.5000  -0.5000  -1.0000

ans =
        0   0.8660   0.8660        0


matlab:

>> xdata = cosd (0:60:360);
>> ydata = sind (0:60:360);
>> h = patch (xdata, ydata, 'b', 'marker', 's'); %% draws hexagon
>> get(h,'xdata'), get(h, 'ydata')
ans =
    1.0000
    0.5000
   -0.5000
   -1.0000
   -0.5000
    0.5000
    1.0000
ans =
         0
    0.8660
    0.8660
         0
   -0.8660
   -0.8660
         0
>> set (h, 'xdata', xdata(1:end-3));
>> get(h,'xdata'), get(h, 'ydata')
ans =
    1.0000
    0.5000
   -0.5000
   -1.0000
ans =
         0
    0.8660
    0.8660
         0

(same effect if you change ydata first. matlab trims xdata to match.)

i couldn't get the repeated warning to duplicate, but it did mess with the following >> prompt, apparently putting it up on the line with the warning.

Also note the orientation difference.  Apparently both store column vectors even if row vectors are supplied, but while matlab's set forces row vectors, octave's set keeps a row vector. and apparently this will trigger the same warning, even if numel(xdata)=numel(ydata): (see below)


>> xdata = cosd (0:60:360);
>> ydata = sind (0:60:360);
>> h = patch (xdata, ydata, 'b', 'marker', 's'); %% draws hexagon
>> get(h, 'xdata'),get(h, 'ydata')
ans =
   1.0000
   0.5000
  -0.5000
  -1.0000
  -0.5000
   0.5000
   1.0000

ans =
        0
   0.8660
   0.8660
        0
  -0.8660
  -0.8660
        0

>> set (h, 'xdata', xdata(1:end));
>> warning: opengl_renderer: x/y/zdata must have the same dimensions.  Not rendering.
get(h, 'xdata'),get(h, 'ydata')
ans =
   1.0000   0.5000  -0.5000  -1.0000  -0.5000   0.5000   1.0000

ans =
        0
   0.8660
   0.8660
        0
  -0.8660
  -0.8660
        0


vs matlab:

>> xdata = cosd (0:60:360);
>> ydata = sind (0:60:360);
>> h = patch (xdata, ydata, 'b', 'marker', 's'); %% draws hexagon
>> get(h,'xdata'), get(h, 'ydata')
ans =
    1.0000
    0.5000
   -0.5000
   -1.0000
   -0.5000
    0.5000
    1.0000
ans =
         0
    0.8660
    0.8660
         0
   -0.8660
   -0.8660
         0
>> xdata(1:end)
ans =
    1.0000    0.5000   -0.5000   -1.0000   -0.5000    0.5000    1.0000
>> set (h, 'xdata', xdata(1:end));
>> get(h,'xdata'), get(h, 'ydata')
ans =
    1.0000
    0.5000
   -0.5000
   -1.0000
   -0.5000
    0.5000
    1.0000
ans =
         0
    0.8660
    0.8660
         0
   -0.8660
   -0.8660
         0


summary:

1 - there's some inconsistency in how octave stores the data (set not forcing column vectors)
2 - in matlab editing either xdata or ydata (or zdata?) automatically trims the other(s) to match.  that seems to be a more significant compatibility error.

I'm also thinking this probably warrants closing this bug report and opening a new one.

Nicholas Jankowski <nrjank>
Group Member
Mon 29 Nov 2021 10:18:30 PM UTC, comment #18: 

Octave sends this because it expects xdata to be the same length as ydata, which seems reasonable to me. According to comment #17, that is also what ML requires when initially drawing a patch with the `patch` function, but it is later more tolerant when manipulating the data using `set` which, IMHO, is not consistent and we should not imitate.

The only part that looks problematic to me is the repeated warning in Octave that we'd probably like to display only once.

Pantxo Diribarne <pantxo>
Group Member
Mon 29 Nov 2021 10:06:23 PM UTC, comment #17: 

the current warning is:

warning: opengl_renderer: x/y/zdata must have the same dimensions.  Not rendering.
warning: called from
    __opengl_print__ at line 204 column 9
    print at line 757 column 16


_opengl_print_ line 204 calls:

 drawnow (gl2ps_device{n}, ['| "' pipeline{n} '"']);


drawnow being a built-in/compiled function inside libinterp/corefcn/graphics.cc, that's as far as I could step.  A quick search, however, shows blocks of code with the same warning msg:

line 9721:

void
patch::properties::update_fvc (void)
{
  if (updating_patch_data)
    return;

  Matrix xd = get_xdata ().matrix_value ();
  Matrix yd = get_ydata ().matrix_value ();
  Matrix zd = get_zdata ().matrix_value ();
  NDArray cd = get_cdata ().array_value ();

  m_bad_data_msg = "";
  if (xd.dims () != yd.dims ()
      || (xd.dims () != zd.dims () && ! zd.isempty ()))
    {
      m_bad_data_msg = "x/y/zdata must have the same dimensions";
      return;
    }


and line 10306:

void
scatter::properties::update_data (void)
{
  Matrix xd = get_xdata ().matrix_value ();
  Matrix yd = get_ydata ().matrix_value ();
  Matrix zd = get_zdata ().matrix_value ();
  Matrix cd = get_cdata ().matrix_value ();
  Matrix sd = get_sizedata ().matrix_value ();

  m_bad_data_msg = "";
  if (xd.dims () != yd.dims ()
      || (xd.dims () != zd.dims () && ! zd.isempty ()))
    {
      m_bad_data_msg = "x/y/zdata must have the same dimensions";
      return;
    }


I assume we're following the patch codeblock, but didn't see a "Not rendering." though, so that must be appended elsewhere.

none of this is dependent on the print command or pdf output given in comment #8.  a simpler test script is:


xdata = cosd (0:60:360);
ydata = sind (0:60:360);
h = patch (xdata, ydata, 'b', 'marker', 's'); %% draws hexagon
set (h, 'xdata', xdata(1:end-1)); %% hexagon minus duplicated last pt
set (h, 'xdata', xdata(1:end-2)); %% draws with only 5 points
set (h, 'xdata', xdata(1:end-3)); %% draws with only 4 points


In Matlab 2021, each of the 'set' lines will trigger a redraw of the figure with the appropriate # of points (indicating set knows to trim ydata to the matching length), whereas Octave gives you the x/y/zdata warning and won't redraw. Noting that both error if you attempt to:

Matlab:

h = patch (xdata(1:end-1), ydata, 'b', 'marker', 's');

Error using patch
Vectors must be the same length.


Octave:

>> h = patch (xdata(1:end-1), ydata, 'b', 'marker', 's');
>> warning: opengl_renderer: x/y/zdata must have the same dimensions.  Not rendering.
warning: opengl_renderer: x/y/zdata must have the same dimensions.  Not rendering.
warning: opengl_renderer: x/y/zdata must have the same dimensions.  Not rendering.

(not sure why the duplicated warnings)

noting that the original bug is seemingly corrected but that the comment #15 warnings persist, retitling the report accordingly.  Also, noting the age of the report and the fact that this can be avoided by setting both x and y data to the same limit, lowering severity/priority. 


Nicholas Jankowski <nrjank>
Group Member
Sat 28 Aug 2021 04:43:06 AM UTC, comment #16: 

in octave 6.3.0 bug still seems to be in the same condition reported in comment #15

comment #0 code no issues.

comment #8 code produces errors mentioned in comment #15

comment #10 code produces no errors.

Nicholas Jankowski <nrjank>
Group Member
Sun 20 Nov 2016 10:44:35 PM UTC, comment #15: 

I am not sure if this issue is still present in Octave 4.2.0.

The code from comment #0 now produces 10 nice bars in the plot (with gnuplot, fltk and qt). So the original issue seems to be FIXED now.

But the code from comment #8 now produces a lot of empty pdf files (only the first pdf file shows a blue patch) and issues a lot of warnings of the following type:


warning: opengl_renderer: x/y/zdata must have the same dimensions.  Not rendering.
warning: called from
    findobj at line 210 column 16
    findall at line 45 column 7
    print at line 400 column 11
    ccc at line 20 column 3


Hartmut <hardy>
Thu 10 Oct 2013 11:27:44 PM UTC, comment #14: 

I have no real objection to a change in severity.  I had elevated it in the hope of getting the attention of someone with better coding skills than I.  Feel free to change is as you see fit.

Ben Abbott <bpabbott>
Group Member
Thu 10 Oct 2013 10:34:32 PM UTC, comment #13: 

We haven't finalized the criteria, but for the last release it was anything >= 4.  Right now, this is the only bug that doesn't fall into either being a regression, segfault, or level >= 5.  So we could simply set the criteria to 5 and above and then this wouldn't count, yet still be marked important.

Rik <rik5>
Group administrator
Thu 10 Oct 2013 10:23:09 PM UTC, comment #12: 

I thought only a blocker (5) would gate the release. Do I have that wrong?

Ben Abbott <bpabbott>
Group Member
Thu 10 Oct 2013 10:13:29 PM UTC, comment #11: 

Ben, this bug is currently marked at severity level 4 which will gate the 3.8 release.  Can you review this bug again and decide whether it continues to warrant a level 4 rating?

Rik <rik5>
Group administrator
Fri 14 Jun 2013 07:52:48 AM UTC, comment #10: 

May only apply to patches


xdata = 1:10;
ydata = rand (1, 10);
h = plot (xdata, ydata, '-s');
set (h, 'xdata', [xdata,xdata])
Warning: line XData length (20) and YData length (10) must be equal
Warning: line XData length (20) and YData length (10) must be equal


After changing the xdata, the figure updates and the line object disappears.

Ben Abbott <bpabbott>
Group Member
Fri 14 Jun 2013 05:45:49 AM UTC, comment #9: 

I'm changing the category, item group, severity, and removing myself as assignee (since this is beyond my reach).

Ben Abbott <bpabbott>
Group Member
Fri 14 Jun 2013 05:41:10 AM UTC, comment #8: 

I've constructed a simple demo that runs in Matlab.


xdata = cosd (0:60:360);
ydata = sind (0:60:360);
figure (1)
reset (gcf ())
set (gcf (), 'papersize', [5, 4], 'paperposition', [0.25, 0.25, 4.5 3.5])
clf ()
axis ([-1.2679 1.2679 -1 1])
h = patch (xdata, ydata, 'b', 'marker', 's');
drawnow ()
plots = 1;
print ('-dpdf', 'plot01.pdf')
for n = [numel(xdata)-1:-1:0, 1:numel(xdata)]
  set (h, 'xdata', xdata(1:n))
  drawnow ()
  plots = plots + 1;
  print ('-dpdf', strrep (sprintf ('plot%2d.pdf', plots), ' ', '0'))
end


I've combined the results into a single file and have attached it.

(file #28315)

Ben Abbott <bpabbott>
Group Member
Fri 14 Jun 2013 01:06:55 AM UTC, comment #7: 

If I understand your question, my impression is that the value is "hidden".  Essentially, something like below is happening.


sz = min (size (xdata), size (ydata));
xdata_to_return = xdata(1:sz(1),1:sz(2));
ydata_to_return = ydata(1:sz(1),1,sz(2));


The modified test you asked for is below.


h = patch (1 + [0 1 0 0], [0 0 1 0], 'b');
xdata = get (h, 'xdata');
ydata = get (h, 'ydata');
set (h, 'ydata', ydata(1:3))
get (h, 'xdata')

ans =

     1
     2
     1

set (h, 'ydata', ydata)
get (h, 'xdata')

ans =

     1
     2
     1
     1


Ben Abbott <bpabbott>
Group Member
Thu 13 Jun 2013 01:45:43 PM UTC, comment #6: 

Could you try the first 2 tests when x(4) is not 0? I'm wondering whether x(4) gets lost or is simply hidden when you change ydata to have 3 elements, then back to 4 elements.

Michael Goffioul <goffioul>
Thu 13 Jun 2013 12:28:37 PM UTC, comment #5: 

I did some experimenting with patch ().  I didn't expect Matlab to work this way.


h = patch ([0 1 0 0], [0 0 1 0], 'b');
xdata = get (h, 'xdata');
ydata = get (h, 'ydata');
set (h, 'ydata', ydata(1:3))
get (h, 'xdata')

ans =

     0
     1
     0

set (h, 'ydata', ydata)
get (h, 'xdata')

ans =

     0
     1
     0
     0

set (h, 'xdata', [xdata; NaN])
get (h, 'ydata')

ans =

     0
     0
     1
     0

get (h, 'xdata')

ans =

     0
     1
     0
     0

set (h, 'ydata', [ydata; NaN])
get (h, 'xdata')

ans =

     0
     1
     0
     0
   NaN


It appears that Matlab's set() and get() functions are doing something special.

Ben Abbott <bpabbott>
Group Member
Thu 13 Jun 2013 10:56:58 AM UTC, comment #4: 

I'm pretty sure Matlab has the equivalent of Octave's addlistener for graphics object, but it might be an internal function. You'll have to dig a bit to find it.

Michael Goffioul <goffioul>
Thu 13 Jun 2013 05:31:58 AM UTC, comment #3: 

To fix the {x,y,z}data listeners for bar() and area() I modified the {x,y,z}data listeners for patch objects, and that change fixed this problem.

I'lll do some more testing and push the changeset

Ben Abbott <bpabbott>
Group Member
Thu 13 Jun 2013 03:25:11 AM UTC, comment #2: 

I'm happy to give it a try.  Unfortunately, I'm not sure how to do it.  Octave's addlistener() function is not present in Matlab (they have one what works with classdef).

Any thoughts on how I'd manage a test?

Meanwhile,  doing things like,


clf
axis ([0, 10, 0, 10])
h = text (0.5, 0.5, 'foo');
set (h, 'units', 'normalized', 'position', [0.2, 0.5, 0])
h = text (0.5, 0.5, 'bar');
set (h, 'position', [0.2, 0.5, 0], 'units', 'normalized')


indicates that Octave and Matlab each update after each property is set.  So my impression is that the way Octave's listeners are working is consistent with how Matlab updates.

Ben Abbott <bpabbott>
Group Member
Thu 13 Jun 2013 03:11:52 AM UTC, comment #1: 

This makes me wonder how/when listeners are executed in Matlab. Ben, would you be able to verify it? Create a "bar" graph, install a listener on the xdata and ydata (which will print the corresponding values, for instance) and use a single "set" call to change both properties at the same time.

I'm wondering whether the execution of all listeners is delayed until all properties have actually been changed.

Michael Goffioul <goffioul>
Thu 13 Jun 2013 02:40:49 AM UTC, original submission:  

The code below should ultimately render 10 bars of random height.


 N = 10;
 xdata = 1:N;
 ydata = rand (1, N);
 h = bar (xdata (1));
 xlim ([0, 11])
 for n = 2:numel(xdata)
   set (h, "xdata", xdata(1:n), "ydata", ydata(1:n))
   drawnow ()
   pause (0.2)
 end


The fltk toolkit only renders the first bar.

Ben Abbott <bpabbott>
Group Member

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #28315:  patch_demo.pdf added by bpabbott (123KiB - application/pdf)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by nrjank (Posted a comment)
  • -email is unavailable- added by pantxo (Updated the item)
  • -email is unavailable- added by hardy (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by bpabbott (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 19 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2021-11-30 nrjank StatusIn Progress Fixed
        Open/ClosedOpen Closed
        Summarypatch - matlab compatibility - changing xdata length produces dimension warning patch {x,y,z,c}data properties are not independent
    2021-11-29 nrjank Severity3 - Normal 2 - Minor
        Priority5 - Normal 3 - Low
        Summarypatch {x,y,z,c}data properties are not independent patch - matlab compatibility - changing xdata length produces dimension warning
    2019-09-06 pantxo CategoryInterpreter Plotting with OpenGL
    2013-10-11 rik5 Severity4 - Important 3 - Normal
    2013-06-14 bpabbott Summary{x,y,z,c}data properties are not independent patch {x,y,z,c}data properties are not independent
    2013-06-14 bpabbott CategoryPlotting with OpenGL Interpreter
        Severity3 - Normal 4 - Important
        Item GroupIncorrect Result Matlab Compatibility
        Assigned tobpabbott None
        SummaryOpenGL: change to {x,y}data does not update bar() {x,y,z,c}data properties are not independent
    2013-06-14 bpabbott Attached File- Added patch_demo.pdf, #28315
    2013-06-13 bpabbott Assigned toNone bpabbott
    2013-06-13 bpabbott StatusNone In Progress
    2013-06-13 bpabbott Summaryfltk: change to {x,y}data does not update bar() OpenGL: change to {x,y}data does not update bar()
    2013-06-13 bpabbott Summarychange to {x,y}data does not update bar() fltk: change to {x,y}data does not update bar()

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code