Menu

#2679 Interactive rotation of 3D plots in a multiplot context and inline data broke in 6.0

None
closed-not-a-bug
nobody
None
2024-05-31
2024-01-16
SiegeLord
No

Version: gnuplot 6.0 patchlevel 0
Platform: Linux
Terminal: wxt

Steps to reproduce:

  1. Run gnuplot -p test.gnuplot on a file with the following contents, using the wxt terminal:
set multiplot
splot "-" using 1:2:3 with lines
1 2 3
4 5 6
e
unset multiplot
  1. Try rotating the plot (left click and drag)
  2. On 6.0, this closes the terminal. This works fine on 5.4 patchlevel 2.

If the multiplot commands are removed, it functions fine on both. If loading from a file, this functions fine. If running this within an interactive gnuplot instance (via load "test.gnuplot") the same reproduction causes it to freeze.

Discussion

  • Ethan Merritt

    Ethan Merritt - 2024-01-17

    Thank you for the report.

    No gnuplot version prior to 6.0 was capable of mouse rotation or a true "replot" in multiplot mode. Instead the program would simply ignore the multiplot status and issue a "replot" for the single most recent plot command. In your reproducer there is only one plot in the multiplot, so it is hard to tell the difference, but if you add a second plot to the multiplot it will become obvious.

    So yes, you are correct. Version 6.0 cannot deal with pseudofile "-" when replaying a multiplot sequence and since, unlike earlier gnuplot versions, it can replay the command sequence to regenerate a full muliplot it also does not fall back to issuing a one-plot-only replot instead.

    Your two main options are

    (1) If it really is just a single plot, don't wrap it inside a multiplot.

    (2) Instead of providing in-line data via pseudofile "-", use a datablock.

    set multiplot
    $DATA << EOD
    1 2 3
    4 5 6
    EOD
    splot $DATA using 1:2:3 with lines
    unset multiplot
    

    Both of those options work, so far as I can tell, with the initial 6.0 release. However, playing with this test case showed some fixable ugliness. Here is the commit message for a fix applied to the 6.0 stable branch:

    commit 7125285f0df1904dbc025d28dfb5cfa4ece806af (HEAD -> branch-6-0-stable, origin/branch-6-0-stable)
    Date:   Tue Jan 16 21:27:15 2024 -0800
    
        Treat use of pseudofile '-' inside a multiplot as an error
    
        1) "remultiplot" or "replot" or mousing in general can now replay
        the command sequence that created a multiplot.  If this includes
        a plot command using pseudofile '-' as a data source, it would fail.
        Worse, depending on the terminal type it might hang (x11, wxt, others?)
        or even segfault (wxt but not 100% reproducible).
        Related: Bug #2679
    
        - catch this case in df_gets() and call
                int_error(NO_CARET, "cannot read data from '-' during remultiplot");
    
        2) Fortunately it works to define and use a datablock instead.
        This was working already, but $GPVAL_LAST_MULTIPLOT was left with an
        fragmentary datablock definition line.  It was filtered out during
        multiplot replay, but if saved and reloaded this would be an error.
    
        - do not pass datablock definition lines to append_multiplot_line()
    
        3) The wxt terminal in particular behaved badly on the Bug #2679
        reproducer.  Hitting ^C to regain control produced a spurious error
        "input select error" and occasionally a segfault.
    
        - the ^C is now caught cleanly in wxt_waitforinput() without calling
        int_error().
    
        I did not pin down the cause of the sporadic segfaults.
    

    It may be that your subsequent report https://sourceforge.net/p/gnuplot/bugs/2680/ is a better reproducer for that same segfault. I haven't looked at it yet.

     

    Last edit: Ethan Merritt 2024-01-17
  • SiegeLord

    SiegeLord - 2024-01-17

    Thanks, that at least clarifies expectations. "-" was always wonky with replot, and I guess 6.0 broke it inadvertently. Sadly, I cannot use datablocks since they don't support binary data. Binary data is used for speed: generating and parsing ascii number representations has occasionally been a bottleneck. For now, I worked around this via the use of temporary files.

    This is all in a context of a library that pipes commands/data into gnuplot. Historically "-" has been an acceptable solution. Ideally, however, there'd be a way to use binary datablocks or some other way to inline persistent data in a binary format.

     
    • Ethan Merritt

      Ethan Merritt - 2024-01-17

      Ah. Binary data. That clarifies the issue. But where does the need for "multiplot" enter into this? Since the 3D interaction you saw from earlier gnuplot versions was the result of the program ignoring "multiplot" while replotting or mousing, can you not just avoid setting it in the first place? That should produce the same result as before.

      Let me briefly provide a bit more background information. Maybe it will suggest to you a possible change or addition to the code that would meet your needs.

      The reason 3D mouse rotation works for a single plot (not a multiplot) is that the program realizes that it is undesirable to reread the data for each incremental redraw so it internally issues a refresh command rather than a replot command after incrementing the view angles. refresh reuses the active plot structure including the data values already stored there rather than starting again with an empty plot structure and reading data into it. It works for a single plot because the program state variables (scale, axis range, key settings, plot styles, etc) match the content of the active plot structure. It would not work for a multiplot because each component subplot structure was constructed to work with a specific set of state variables; in general these differ from one subplot to the next and only the most recently drawn subplot matches the current program state variables. So dropping out of the multiplot state and using the current program state with the saved structure (including the data values) for only the most recent plot is possible and that is what earlier program versions did. Version 6 instead replays the sequence of commands to recreate the appropriate program state and plot structure for each subplot as it proceeds. It starts the entire replay process with a clean slate and an empty plot structure, so previous data values are lost.

      I suppose it would be possible to add a command to explicitly cancel the previous multiplot sequence, leaving only the most recently drawn plot as active. That would be equivalent to what older gnuplot versions did. But if you only want to keep the one plot, why create a multiplot in the first place? I also suppose it would be possible to treat a multiplot containing only a single component as a special case. But again, what is the scenario where would you need to wrap a single plot inside the multiplot framework?

       
      • SiegeLord

        SiegeLord - 2024-02-06

        I used multiplot unconditionally for simplicity. There's no reason I can't disable it for single plots.

         
  • Ethan Merritt

    Ethan Merritt - 2024-05-31
    • status: open --> closed-not-a-bug
    • Group: -->
    • Priority: -->
     

Log in to post a comment.