Menu

#812 New plotting style 'hsteps' and 'vsteps'

Version 5
closed-accepted
nobody
None
5
2023-10-02
2023-07-30
No

This patch contains a proposal for a new hsteps style for drawing a
step-like plot with N horizontal line segments for N sequentia
l data points. It is also proposed to introduce the vsteps style, which swaps the roles of the x and y axes of hsteps.

For more information, see the attached PDF document ('About_Hsteps_Patch.pdf'). Source code for figures in the documents are also attached ('figures.tgz').

I would appreciate it if you could consider this proposal.

3 Attachments

Discussion

1 2 > >> (Page 1 of 2)
  • Ethan Merritt

    Ethan Merritt - 2023-08-09

    I have looked at the code itself only at a quick glance. The questions below
    are from reading the About document and playing a little bit with the examples.

    • Why is it necessary or useful to have a separate "width" keyword
      when you can simply place the same value in the "using" specifier?
      plot $data using 1:2:(width) with hsteps

    • What is the intent or rationale for what happens when
      the width of a step, either from column 3 or from the "width" keyword,
      is greater than the interval to the adjacent point?

    • I find the "y=NaN" option very confusing because it doesn't seem to
      have anything to do with y values. If I understand correctly, it
      really means "connect the endpoints of each step to the endpoints
      of the adjacent steps". Right? In which case I think it would be
      clearer to make it a separate keyword, perhaps a three-way choice
      {split|link|nolink}
      I don't love "split" as a keyword either, but I don't have a better
      suggestion at the moment. "boxes"? "drop"? "verticals"?

    • I was confused by the effect of the fillstyle keyword "border",
      which seems not to apply separately to each fill box.
      I suppose this makes it more like "with filledcurves" than like
      "with boxes" or "with histograms", but it was not what I expected.

    • How many of the existing plot styles steps/histeps/fsteps/fillsteps
      can be reproduced using the new hsteps style? Could we simplify the
      code base by emulating them? I don't mean to deprecate the older
      commands, just to implement them by replacing the existing code
      with a wrapper around the new code. Rather than having separate
      parameters hsteps_* in struct curve_points, define a new structure
      that holds these and any other flags that might be needed to emulate
      the old styles. Then the "plot" command can fill them in, place
      a pointer in the plot header, and funnel both the old and new styles
      through the new code.

    • Do you see a way to combine the new option with histogram plotting
      so that it would satisfy previous feature request 425?
      https://sourceforge.net/p/gnuplot/feature-requests/425/

     
    • Hiroki Motoyoshi

      Thanks for the reply.

      The intended drawing target of the hsteps style is a staircase curve drawn with continuous data, like steps, fsteps and histeps. Due to my greed, there are variations in the shape of the connecting lines, but basically, the style is for drawing curves. Therefore, the hsteps style implements functionality similar to fillsteps and filledcurves concerning filling.

      So I think you expected a hsteps style border to have a box border as drawn with boxes or histogram because I did not fully explain the above points.

      • Why is it necessary or useful to have a separate "width" keyword when you can simply place the same value in the "using" specifier?

      Well, I didn't realize it until you pointed it out. In the implementation process, I first introduced the width keyword and then added the width specification in the 3rd column. So I may have been careless about that.

      OK. Since it doesn't seem problematic, I will eliminate the width keyword.

      • What is the intent or rationale for what happens when the width of a step, either from column 3 or from the "width" keyword, is greater than the interval to the adjacent point?

      What happens is that it draws the line as it is according to the input data. If width is specified, the horizontal line is drawn according to the given point, direction, and length, without regard to the distance between adjacent points. The connecting line is then drawn from the endpoint of the current line segment to the beginning point of the next line segment in data order. However, I don't think that a prohibition or warning against a large-width specification is not necessary.

      Attached example "large_width.webp"

      • I find the "y=NaN" option very confusing because it doesn't seem to have anything to do with y values. If I understand correctly, it really means "connect the endpoints of each step to the endpoints of the adjacent steps". Right? In which case I think it would be clearer to make it a separate keyword, perhaps a three-way choice {split|link|nolink} I don't love "split" as a keyword either, but I don't have a better suggestion at the moment. "boxes"? "drop"? "verticals"?

      I agree that it is confusing expression.

      However, I think the behavior of "y=NaN" is a bit different from your understanding. What this option is intended to do is to eliminate the baseline. Since the baseline is eliminated, there is no reason to draw a vertical line at each end or a connecting line along the baseline. So, as it must, the connecting lines will connect the endpoints of each horizontal line segment. Also, the fill is supposed to fill the space between the horizontal segments and the baseline, but with the baseline gone, there is no longer any reason to fill it. Therefore, when this is specified, only the horizontal line segments and the connecting lines between their endpoints will be drawn (even if a fill is specified). The above is a conceptual explanation, but it is intentionally implemented in this patch to make it happen.

      If we have a better keyword that means "eliminate the baseline", I would be happy to change it to that (ex. "nobase$line" ...).

      • I was confused by the effect of the fillstyle keyword "border", which seems not to apply separately to each fill box. I suppose this makes it more like "with filledcurves" than like "with boxes" or "with histograms", but it was not what I expected.

      Again, I consider the hsteps style to be a style for drawing curves.

      As you felt, the filling of the hsteps style is more like fillsteps or filledcurves.
      As only the envelope by the curves of the fill is to be used as a border, the baseline that is tangential to the fill area is excluded from the border. Therefore, the border does not entirely enclose the filled area.

      As you can see from the implementation, the hsteps style draws the connected areas in polygons all at once, just like filledcurves. Note that the hsteps style does not draw a series of boxes in a row, and does not produce the vertical streak artifact seen in cairo terminals for full-width boxes style.

      • How many of the existing plot styles steps/histeps/fsteps/fillsteps can be reproduced using the new hsteps style? Could we simplify the code base by emulating them? I don't mean to deprecate the older commands, just to implement them by replacing the existing code with a wrapper around the new code. Rather than having separate parameters hsteps_* in struct curve_points, define a new structure that holds these and any other flags that might be needed to emulate the old styles. Then the "plot" command can fill them in, place a pointer in the plot header, and funnel both the old and new styles through the new code.

      The steps/fsteps/fillsteps curves can be reproduced precisely, although a slight code change is required. These styles draw only N-1 horizontal segments for N data. In other words, they do not draw the horizontal line segment of the last data. They also do not draw vertical lines at both ends. They are always full-width. We need to add internal flags and code to force such behavior in emulated mode. If we can do that, we can also introduce fillstyle into steps and fsteps themselves.

      On the other hand, the histeps style internally sorts the data to be drawn along the x-axis, and this behavior is incompatible with the implementation of hsteps. It is possible to emulate histeps with hsteps functionality if we allow for the incompatibility of not implementing x-axis sorting.

      Also, I need to investigate further whether incompatibility occurs when there are NaNs or empty lines in the input data.

      If it is something as simple as this ticket, it is possible.

      $data << EOD
      1920 55 21 24
      1940 45 26 29
      1960 33 29 38
      1980 11 34 55
      2000 5 30 65
      EOD
      
      bw = 0.7
      set boxwidth bw
      set style histogram rowstacked
      unset key
      
      plot $data using 0:2:(bw)       with hsteps y=NaN lt -1, \
           ''    using 0:($2+$3):(bw) with hsteps y=NaN lt -1, \
           ''    using 2:xtic(1)      with hist fs solid, \
           ''    using 3              with hist fs solid, \
           ''    using 4              with hist fs solid, \
      

      I am unsure if the combination with histogram can be done automatically because you need to know the position and width of the histogram bars. It would work with a bar graph you constructed using boxxy or boxes. Note, however, that even if you only need the connecting lines, the horizontal line segments will always be drawn together. Other objects should hide these horizontal lines as an extra.

       

      Last edit: Hiroki Motoyoshi 2023-08-10
  • Ethan Merritt

    Ethan Merritt - 2023-08-11

    10 Aug 2023
    Here is a second round of comments.

    • Perhaps I am overlooking a relevant application, but I do not see a use
      for "split" mode. Why would one ever use this rather than "with boxes"?
      As I see it, "with hsteps" offers three useful modes so far.
      1) The current default that drops a vertical line either to the next
      step or to the baseline depending on step width.
      Perhaps if adjacent steps overlap (one is wider than expected)
      the vertical should stop when it hits the other step rather than
      continuing through it to hit the baseline.
      2) The current "nolink"
      3) The current "y=NaN" which I still think should instead be
      a separate keyword.
      So I suggest that these should be three mutually exclusive options
      plot DATA with hsteps {default|nolink|link}
      There might be better names for the modes, but I don't have any to offer
      at the moment.

    • I convey a comment from geneticist colleague who uses gnuplot to
      prepare figures. She is particularly enthusiastic about the new
      capability shown in Figure 11 of your About document.

    • The attached plot (png image) shows two behaviours that I find unexpected.
      Both are illustrated by the plot
      array A = [2, 1, 6, 3, 7, 4, 5, 3, 5, 2, 0, 5]
      plot A using 1:2:(1) with hsteps above y=2.5 fs solid 0.5 border

    Autoscaling of the endpoints does not work as I would expect.
    In particular xmax does not extend far enough to hold the full curve.
    I think this can be fixed in plot2d:get_data() by correctly calculating
    xlow and xhigh before passing them to store2d_point().

    I do not think that above/below should affect the curve itself,
    only the fill area.

    Code

    I have two overall comments on the new C code. Both are from the perspective of consistency with the existing gnuplot code base.

    The first is that I would prefer to drop the idea of a separate "vsteps" plot style. Yes there have been requests dating back at least 20 years that gnuplot should provide some "plot everything sideways" option so that the independent variable runs vertically and the dependent variable runs horizontally. And maybe it would have been better to design it that way from the start. But duplicating large blocks of code for one plot style rather than addressing the program as a whole is IMHO not a good way to go. I prefer to admit that the original design was imperfect and accept those limitations. Gnuplot was not designed to produce vertical plots, just as gnuplot was not designed to provide true 3D graphics.

    The second is that everywhere else in the gnuplot code, variables named point or points refer to a structure of type coordinate. E.g.
    struct coordinate *points = plot->points;

    However the new code for plot_hsteps() defines a different structure hstep_point that serves almost the same purpose but does not overlay struct coordinate. It then tries to hide the incompatibility by using #define macros to substitute map_u(points[i].ul) for what would normally be map_x(points[i].xlow) and so on. I find this very misleading when I try to read the code because the "points" structures are not compatible. Furthermore I worry that the code might break depending on the platform+configuration sizes of fields with type "coordval", "intgr", etc.

    Please use the existing point coordinate structure and field names. If additional flag bits are needed (hstep_point.state) then for now you can use coordinate.extra. That field is new in version 6. The original idea was that it would be present or absent depending on the platform and used optionally if it was present. But it seems that new version 6 code is increasingly relying on this field to be present. Maybe it should be given a better name ("options"? "private"? "temp"?) and promoted to a permanent member of the structure that is always present.

     
  • Hiroki Motoyoshi

    A patch (v2) incorporating the content of the exchange so far and the revised documentation is attached.

    The main changes in patch v1->v2 are as follows,


    Specification

    • remove vsteps style
    • remove width keyword
    • remove split keyword
    • replace the role of y=NaN option to link keyword
    • nolink also makes the baseline undefined

    Code

    • revert the coordinate designation (u,v) to (x,y)
    • use coordinate struct instead of histep_point struct
    • introduce of pilot implementation of steps/fsteps/fillsteps/histeps emulation

    The following is a short reply to the comments so far.

    The first is that I would prefer to drop the idea of a separate "vsteps" plot style.

    I am in the field of meteorology, where I have the opportunity to chart the vertical profiles of weather elements. That's where I wanted to make use of vsteps. However, I would like to concentrate here on the introduction of hsteps and leave the proposal for vsteps for another time.

    Please use the existing point coordinate structure and field names.

    The coordinate struct is now used. Variables required at each point, such as 'state' and 'gap', are now allocated separately.

    Why is it necessary or useful to have a separate "width" keyword when you can simply place the same value in the "using" specifier?

    In the new patch, the width option has been removed.

    Why would one ever use this rather than "with boxes"?

    It was implemented with the intention of being used with vsteps.
    But, in the new patch, the split option has been removed
    along with the removal of vsteps.

    So I suggest that these should be three mutually exclusive options
    plot DATA with hsteps {default|nolink|link}

    In the new patch, I use the name link instead of 'y=NaN'.

    The 'link' option (originally y=NaN) makes the baseline undefined. In conjunction with this, the 'nolink' option has changed also to make the baseline undefined.

    I do not think that above/below should affect the curve itself, only the fill area.

    It has been fixed in the new patch.

    Autoscaling of the endpoints does not work as I would expect. In particular xmax does not extend far enough to hold the full curve. I think this can be fixed in plot2d:get_data() by correctly calculating xlow and xhigh before passing them to store2d_point().

    It has been partialy implemented in the new patch. If the width is given by 3rd column, xlow/xhigh is set in get_data() before passing them to store2d_point(). If the width is not explicitly given, autoscaling is not work correctly because of the lack of ability of the information of the adjacent segments in get_data().

    How many of the existing plot styles steps/histeps/fsteps/fillsteps can be reproduced using the new hsteps style?

    Pilot implementation of steps/fsteps/fillsteps/histeps emulation is included in the new patch. The original function plot_steps ... are left intact, so it is possible to immediately revert to the original behaviour.

     

    Last edit: Hiroki Motoyoshi 2023-08-13
    • Hiroki Motoyoshi

      Here is patch v2.1 which fixes some bugs in patch v2.

      v.2 -> v2.1

      • fixed broken fillsteps emulation
      • fixed double free of 'plot->points' array
      • fixed memory leak of 'state' and 'gap' array
       
  • Hiroki Motoyoshi

    I changed the above/below behavior as Ethan mentioned.
    But, I want to revert it as in original patch (v1).
    That is, the above/below option restricts the border drawing area as well as the fill area.
    This is because expression through v1 behaviour is more flexible than v2 behaviour.

    First of all, the second figure of Ethan's attached file 'above_below.png' is somewhat incorrect regarding the handling of baselines. The option 'above y=2.5' defines the lowest limit of filling at y=2.5 and simultainously it defines the baseline at y=2.5.

    Anyway, the second figure in 'above_below.png' can be realised even in original patch (v1).

    array A = [2, 1, 6, 3, 7, 4, 5, 3, 5, 2, 0, 5]
    plot A using 1:2:(1) with hsteps above y=2.5 fs solid 0.5 noborder,\
         A using 1:2:(1) with hsteps lw 2
    

    And original patch (v1) has the expression like the following,

    set xrange [0:13]
    array A = [2, 1, 6, 3, 7, 4, 5, 3, 5, 2, 0, 5]
    plot A using 1:2:(1) with hsteps above y=2.5 fs solid 0.5 border lw 2 lc "red",\
         A using 1:2:(1) with hsteps below y=2.5 fs solid 0.5 border lw 2 lc "blue"
    

    The resulting diagram is attached. This expression can't be obtained by the new patch (v2).

    I think it is a natural association or extension of filledcurves or fillsteps styles.

    set title "fillsteps"
    plot A using 1:2 with fillsteps above y=2.5 fs solid 0.5 border lw 2 lc "red",\
         A using 1:2 with fillsteps below y=2.5 fs solid 0.5 border lw 2 lc "blue",\
         A using 1:2 with points pt 7 lt black
    
    set title "filledcurves"
    plot A using 1:2 with filledcurves above y=2.5 fs solid 0.5 border lw 2 lc "red",\
         A using 1:2 with filledcurves below y=2.5 fs solid 0.5 border lw 2 lc "blue",\
         A using 1:2 with points pt 7 lt black
    

    I do not think that above/below should affect the curve itself, only the fill area.

    Are there any other styles in which the border behaves like this way?

     

    Last edit: Hiroki Motoyoshi 2023-08-13
  • Hiroki Motoyoshi

    I removed the 'split' keyword in patch v.2, and I wrote,

    Why would one ever use this rather than "with boxes"?

    It was implemented with the intention of being used with vsteps. But, in the new patch, the split option has been removed along with the removal of vsteps.

    Sorry, but, there are some examples to describe I needed this option, although you might feel it is a slight difference. Please, check the following sample codes which show the different aspect of 'hsteps split' from 'boxes'.

    First example

    Box expression of unevenly spaced data.

    $data <<EOD
    # Rmin Count1 Count2
    0.01 1.2e5  8.2e4
    0.02 5.0e4  9.0e3
    0.05 1.1e4  2.3e3
    0.1  5.8e3  7.2e2
    0.2  1.2e3  3.0e2
    0.5  6.2e2  8.1e1
    1.0  2.4e2  3.7e1
    2.0  9.3e1  1.3e1
    5.0  NaN    NaN
    EOD
    
    set log y
    set log x
    set xrange [0.005:10]
    set yrange [1:1e6]
    set xlabel "Radius (mm)"
    set ylabel "Count"
    set ytics format "10^{%T}"
    
    unset key
    
    plot $data using 1:2 with hsteps split forward lw 3
    

    To draw this with boxes, more complex data preparation seem to be needed, because
    the boxes style don't have forward or backward

    Second example

    "hsteps split" does not draw baseline as border.

    $data <<EOD
    # Category G1(%) G2(%)
    A 30 70
    B 20 80
    C 40 60
    D 25 75
    E 60 40
    F 50 50
    EOD
    
    set lmargin screen 0.25
    set rmargin screen 0.75
    set yrange [-100:100]
    set xrange [-1:6] 
    set xtics ("100" -100, "50" -50, "0" 0, "50" 50, "100" 100)
    set ytics scale 0
    unset key
    
    set grid xtics
    
    set title "histeps split"
    plot $data using 0:2:(0.6):xtic(1) with hsteps split fill solid 0.5 border lw 3, \
         $data using 0:(-$3):(0.6)     with hsteps split fill solid 0.5 border lw 3
    

    Here is boxes version.

    set title "boxes"
    plot $data using 0:2:(0.6):xtic(1) with boxes fill solid 0.5 border lw 3, \
         $data using 0:(-$3):(0.6)     with boxes fill solid 0.5 border lw 3
    

    The baseline (y=0) is shared by two plots and the baseline of first plot is overrided by the baseline of second plot.

     
    • Ethan Merritt

      Ethan Merritt - 2023-08-14

      OK, those are good examples. I concede the point that the forward/back options allow layouts that "with boxes" does not provide.

      I am so used to boxes whose border goes all the way around that the missing border along the baseline looks odd to me, but I guess it is entirely a matter of preference.

      Let me have a couple of days to look at your version 2.1

       
      • Hiroki Motoyoshi

        Thank you for your positive comments regarding the 'split' keyword.

        Aside from that, I would be very pleased if you could look at patch v2.1, which includes various fixes.

         
        • Ethan Merritt

          Ethan Merritt - 2023-08-16

          The code in patch 2.1 looks pretty good. I found only two issues.

          • The first plot in existing demo timedat.dem , which using "with fsteps", fails to reproduce previous output. I think this is because the new code reveals a problem with parsing the plot command that was already there. The demo uses "set style data fsteps" and does not use "with fsteps" in the plot command. Because of this the code in eval_plots() does not call parse_hsteps() and the emulation of fsteps doesn't happen. I will look into this further, since it seems to be an existing weakness in the code that should be fixed anyway.

          • The macro CHECK_BASELINE_OPTION() is called repeatedly, but I do not understand why this check is necessary at all. The error message is that 'link|nolink' and 'above|below' are incompatible. Setting y=<baseline> may currently be ignored for the link/nolink options, but that doesn't make it "incompatible". There are plenty of other parameters in the program that are simply ignored when not relevant to the current plot.</baseline>

            Omitting the CHECK_BASELINE_OPTION calls would allow merging the code after the FIXME in parse_hsteps() into get_filledcurves_style_options().
            Or perhaps the checks can be kept but made only once, after parsing the plot options?

           
          • Hiroki Motoyoshi

            The first plot in existing demo timedat.dem , which using "with fsteps", fails to reproduce previous output.

            Indeed, the current code only prepares for the emulation of "steps/fsteps/histeps/fillsteps" in the parsing of 'plot ... with'.

            The macro CHECK_BASELINE_OPTION() is called repeatedly, but I do not understand why this check is necessary at all.

            I checked that 'y=<baseline>/above/below' should be prohibited when link/nolink is specified, as the baseline is undefined. Multiple CHECK_BASELINE_OPTION calls were made because I wanted to indicate the carat to that option when it would be found.</baseline>

            I want to remove the unnecessary checks as it means that we don't necessarily need to check the consistency of all options.

            If we remove the CHECK_BASELINE_OPTION, we need to decide what should be done about the effect when "above/below" is given for "nolink/link". What is your thought on the comment regarding the effect of above/below?

            Omitting the CHECK_BASELINE_OPTION calls would allow merging the code after the FIXME in parse_hsteps() into get_filledcurves_style_options().

            I had the problem that the 'get_filledcurves_style_options()' reset the 'fco->oneside' parameter. Could it be that 'above|below' must always come before 'y=<baseline>'? If so, we can replace that part with 'get_filledcurves_style_options()'.</baseline>

            Or perhaps the checks can be kept but made only once, after parsing the plot options?

            This method may be acceptable if the display of carats is less critical.

             
  • Ethan Merritt

    Ethan Merritt - 2023-08-17

    Answers to various questions:

    • Until now the only plot style that recognizes above/below as keywords is "with filledcurves". That plot style produces only the fill areas. It does not draw a border. If you want a border you must draw it separately using "with lines". So it is not an exact precedent for "with hsteps fillstyle solid". I initially expected that "hsteps above/below" would only affect the fill area. Having it also affect the border is not terrible; but it's not what I expected.

    • There are lots of cases where if you set a parameter to NaN it will produce a bad plot. Consider set yrange [0:NaN] or set boxwidth NaN. I think that adding special tests for something like that is not warranted. At some point you have to trust that the user will not "shoot themself in the foot" (a famous saying in the unix world).

    • I may not understand your idea of a "baseline". Most plot styles do not have such a concept, at least not something separate from the plot border. What is the problem if "with hsteps nolink" does not use a baseline? That mode also does not have a fill area, so I would expect it to ignore above/below anyway.

    • I think it is OK if if "above" or "below" must come before "y=<foo>". That is the natural way to say it in English.</foo>

    Anything else?

     

    Last edit: Ethan Merritt 2023-08-17
    • Hiroki Motoyoshi

      Thank you for your comments.

      I initially expected that "hsteps above/below" would only affect the fill area. Having it also affect the border is not terrible; but it's not what I expected.

      If you don't mind, I would like to revert to patch v1 behavior for drawing 'above/below'. And I would like to leave open the possibility of changing to v2.1 behavior if there are problems by the time of release.

      There are lots of cases where if you set a parameter to NaN it will produce a bad plot. Consider set yrange [0:NaN] or set boxwidth NaN. I think that adding special tests for something like that is not warranted. At some point you have to trust that the user will not "shoot themself in the foot" (a famous saying in the unix world).

      The 'y=NaN' check will be eliminated because of the modification to use 'get_filledcurves_style_options()' in parse_hsteps().

      I may not understand your idea of a "baseline". Most plot styles do not have such a concept, at least not something separate from the plot border.

      Although not explicitly called "baseline", several styles treat y=0 specially (boxes/impulse/histeps/fillsteps/filledcurves). The "baseline" in 'with hsteps' has the meanings

      (a) destination of the vertical lines on both ends (See 'histeps')
      (b) lower or upper limit of fill area (See 'filledcurves', 'fillsteps')
      (c) level of the horizontal lines in the pulse-shaped connecting lines (no correspondense)

      What is the problem if "with hsteps nolink" does not use a baseline?

      In patch v2.1, 'with hsteps nolink' already does not have fill and baseline as same as 'with hsteps link' (originally 'y=NaN').

      That mode also does not have a fill area, so I would expect it to ignore above/below anyway.

      To do so, the codes to force to ignore the 'above/below' specification may be needed for 'with hsteps link/nolink' in 'parse_hsteps()' or 'plot_hsteps()'.


      The attached file is patch v3, which includes

      • revert 'above/below' behavior to patch v1 (affect both of fill area and border).
      • recover the 'split' option
      • use of get_filledcurves_style_options() in parse_hsteps().
      • remove CHECK_BASELINE_OPTION()
      • force to ignore 'above/below' setting for 'with hsteps link/nolink'

      and does not include

      • modification for 'set style data' or 'set style function' in emulation of steps/fsteps/histeps/fillsteps (need to be investigated)
       
      • Ethan Merritt

        Ethan Merritt - 2023-08-20

        I think it is looking good. Two small patches attached below, to be applied on top of your version 3.
        1. handles the 'set style {data|function}' case for emulation of older plot styles
        2. deals with compiler warnings for unused variables and unused code. Also allows a keyword "baseline" to describe the default state baseline/link/nolink

        I found a few minor remaining issues

        • The key sample does not always match the plot style options. It should not show a filled box in the key if no fill is used in the current plot.
          set style fill solid
          plot $data using 1:2:(0.7) with hsteps link title "this plot has no fill"

        • The choice of color in these same cases is also unexpected. It uses the fillstyle border color even though there is no fill in the plot
                 set style fill solid 0.5 border lt -1
                 plot $data using 1:2:(0.7) lc "red" with hsteps link title "this plot should be red"

        • If the input column 3 value for width is negative, the resulting curve becomes tangled. I think the program should either use the absolute value or treat negative values as meaning "default width"

        • I'm still hoping to think of a keyword with a more obvious meaning than "split".

         
        • Hiroki Motoyoshi

          Thank you for your patches and comments.

          1. handles the 'set style {data|function}' case for emulation of older plot styles

          Did not merge due to the integrated set style data/function support described later.

          1. deals with compiler warnings for unused variables and unused code. Also allows a keyword "baseline" to describe the default state baseline/link/nolink

          Merged.

          The key sample does not always match the plot style options.

          Fixed.

          The choice of color in these same cases is also unexpected.

          Maybe fixed.

          If the input column 3 value for width is negative, the resulting curve becomes tangled. I think the program should either use the absolute value or treat negative values as meaning "default width"

          Modified to treat the negative width as 'default width' (distance to adjacent point) .

          I'm still hoping to think of a keyword with a more obvious meaning than "split".

          'halfbox', 'discrete', 'partition' ...


          Other changes.

          1. Improvement of emulation of 'fillsteps'

          The behavior of the 'fillsteps' style is a bit special. If 'fillstyle' is not specified, it behaves as a 'steps' style, and if 'fillstyle' is specified, only filling is done and no border is drawn.

          2. Supports 'set style data/function' for hsteps and emulations.

          Following the approach of the 'filledcurves' style, the 'set style data/function' command now allows the 'hsteps' styles to be specified, including its options. With this change, The 'steps/fsteps/histeps/fillsteps' styles also can be handled in the same way.
          This is accomplished as follows,
          * Introduced the 'hsteps_opts' structure (gadgets.h).

          typedef struct hsteps_options {
              double offset;
              int    direction;
              TBOOLEAN baseline; 
              TBOOLEAN link;
              TBOOLEAN split;
          } hsteps_opts;
          
          • Added a member 'hsteps_opts hsteps_options' in plot_curves structure (graphics.h)
          • Introduced global variables 'hsteps_opts_data' and 'hsteps_opts_func' (gadgets.c)
          • Changed arguments of parse_hsteps() to 'hsteps_opts' and 'filledcurves_opts' instead of 'plot_curve' (misc.c)
          • Defined the function 'hsteps_options_tofile()' so that show/save works for hsteps and emulations (misc.c)

          The attached file "gnuplot_hsteps_v4.patch" is patch v4 includes the changes descrived above. Another attached file "diff_v3_v4.txt" is diff output between v3 and v4.

           
          • Hiroki Motoyoshi

            Minor fixes for the emulation after patch v4.

            • Fixed a mistake in which the 'steps' emulation was set to have baseline introduced in patch v3.
            • Fix for the 'fillsteps' emulation's '{above|below}' option not working.
            • The value of point.z was changed from 0 to -1, meaning "default width". This makes the value of point.z common between hsteps in the case of "default width" and emulation.

            The attached files are patch v4.1 and the difference between v4 and v4.1.

             
            • Hiroki Motoyoshi

              Incompatibilities in 'histeps' regarding sorting of input data still remain.

              The 'histeps' documentation does not contain any description of input data sorting, which has been an undocumented behaviour.

              If the "input data sorting" behaviour of the 'histeps' style needs to be retained, it may be better to remove the 'histeps' style from the emulation by 'plot_hsteps()' function and revert to use the existing 'plot_histeps()' function.

               
              • Ethan Merritt

                Ethan Merritt - 2023-08-23

                You are correct that the sorting step of "with histeps" is undocumented. Also I think it does not usefully handle the case of multiple lines with the same x value.

                For both the old and the new (emulated) versions, if the x coordinates are out of order it is probably best to use

                plot $DATA using 1:2 smooth unique with histeps

                 
                • Hiroki Motoyoshi

                  Thank you for indicating the canonical usage of histeps.

                  Although the sorting step can be implemented in the emulation of 'histeps', I think it is not needed to include the sorting step in the emulation of 'histeps'. Instead, the behavior that the 'histeps' skips the empty line or invalid data should be emulated.
                  The attached small patch for v4.1 supports the emulation of skipping the undefined or invalid data.

                  The following script is an example to demonstrate the difference.

                  $data <<EOD
                  1 5
                  2 8
                  3 10
                  
                  5 7
                  6 5
                  7 3
                  EOD
                  
                  set xrange [-1:9]
                  set yrange [-2:13]
                  
                  plot $data using 1:2 with boxes fs solid 0.5 noborder title "boxes", \
                       $data using 1:2 with histeps lw 4 title "histeps", \
                       $data using 1:2 with hsteps lw 2 title "hsteps"
                  
                   
                  • Ethan Merritt

                    Ethan Merritt - 2023-08-24

                    I am not clear on exactly what problem you are trying to fix with that patch, but I think it makes things worse rather than better. The usual reason to have empty lines in a file is to separate data sets. If you ignore the empty lines then the data sets are mixed, with a bad result. Consider the attached test case before and after the patch.

                    I think the emulation of histeps is OK without the patch for simple cases, and for complicated cases like multiple data sets in a single file I am not convinced that the original histeps code made sense to begin with. Running that same attached test case through version 5.4 produces a plot that looks nice but I cannot figure out what it is supposed to represent!

                     
                    • Hiroki Motoyoshi

                      Thank you for your sample script.

                      Your sample script really shows that the 'histeps' style is "similar but much different" to 'hsteps'. And my 'sorting step' implementation for trying also failed to reproduce the plots using your sample script :-(

                      So I came to realise that the 'histeps' implementation should remain the original code, not an emulation for compatibility reason.

                       
                      • Ethan Merritt

                        Ethan Merritt - 2023-08-25

                        I have never used any of the steps styles myself for my work, so I have never investigated or tested them thoroughly. I think this series of tests shows there were problems with the original implementation of histeps. Your "emulation" (without the extra patch) in my opinion produces more reasonable output than the original.

                        Here is an updated test case with a second plot that shows that the new code produces the expected plot, while the original histeps code does something strange with the multi-dataset case.

                        I suggest to keep the emulated code.

                         
                        • Hiroki Motoyoshi

                          I suggest to keep the emulated code.

                          Thanks for your advice.

                          OK, I will revert the histeps emulation code to the initial one. On top of that, I would like to add the explicit fillstyle option to histeps as well.

                          Next, about 'split': I think 'split' should be an exclusive option with 'baseline/link/nolink', which is an option to specify the shape of the connecting line. If so, a better word for the shape of the connecting line should be like ' sides', 'sidewalls' or 'edges', which should have the meaning of a vertical line on each side of a horizontal line segment.

                          Do you have any idea for such words?

                           

                          Last edit: Hiroki Motoyoshi 2023-08-26
                          • Ethan Merritt

                            Ethan Merritt - 2023-08-28

                            I think 'split' should be an exclusive option with 'baseline/link/nolink', which is an option to specify the shape of the connecting line. If so, a better word for the shape of the connecting line should be like ' sides', 'sidewalls' or 'edges', which should have the meaning of a vertical line on each side of a horizontal line segment.

                            Do you have any idea for such words?

                            I have been unable to find any generic name for plots that exactly match this style. The best I can come up with to describe what the individual steps look like after adding the left+right edges but removing the connection along the baseline is pillars.

                             
  • Ethan Merritt

    Ethan Merritt - 2023-08-22

    I have gotten sidetracked trying to analyze this use-after-free error that is triggered by rendering the version 3 set of figures with the cairo terminals. The problem is probably in gp_cairo.c, but nothing in the full demo set triggers it so the new hsteps code must use some access pattern or sequence of calls that differs from the existing plot styles.

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.