Skip to content

Conversation

@PaulWessel
Copy link
Member

See discussion in this Forum post for background. This branch implements this feature via a new option to plot: -M[c|s][+gfill][+ppen]. This is a draft implementation so neither this syntax nor behavior is finalised. If you build from this branch you can run this short script:

gmt begin curve png
	gmt math -T0/720/5 -N3/0 T -C1 COSD -C2 3 MUL SIND 4 DIV = both.txt
	gmt math -T0/720/5 -N3/0 T -C1 COSD -C2 3 MUL SIND 4 DIV -C1,2 1 T 200 250 INRANGE SUB 0 NAN MUL = both_NaN.txt
	gmt plot -Mc+p0.25p,- both.txt -W0.25p,- -Bxa90g90+u@. -Byafg -JX15c/3c -R0/720/-1.25/1.5 -l"NaN section"
	gmt plot -Mc+gblue+p1p,green both_NaN.txt -Gred -W1p -l"Long @~l@~ exceeds short"
gmt end show

which plots this:

curve

Some features (as implemented): Here, S0 is the first series and S1 the second series (time or space):

  1. The two segments S0 and S1 can be given as two separate files (-Ms) or as a single file with co-registered series in columns 2 and 3 (-Mc).
  2. Only overlapping segments are filled, meaning if one curve has a shorter or longer extent than the other then obviously no fill can occur where a line has no complement.
  3. One or both segment can contain sections of NaN gaps and no filling will occur there.
  4. Crossings are detected via the x2sys functions.
  5. Optional fill for sections where S0 > S1 can be specified via -Gfill.
  6. Optional fill for sections where S1 > S0 can be specified via -M+gfill.
  7. Line S0 can also be drawn via -Wpen (or do it separately in another plot call).
  8. Line S1 can also be drawn via -M+ppen (or do it separately in another plot call).

Open-ended questions:

  • What other sensible input situations should we consider? For -Ms, is it expected to give two files, each with exactly N segments, and then each segment in table 1 will be paired with the corresponding segment number in table 2? [RIght now N is basically hardwired to 1, but this can change].
  • How should legend issue be handled? Right now you get the -G for rectangle with -W pen drawn. What are options here? Plot both the two fill rectangles if both colors are given? How to pass the two separate labels? Perhaps -G label via -l and -M+g label via +llabel modifier to -M?
  • Other features or issues? Please comment (maybe @gd-a is interested in this, too?)

@PaulWessel PaulWessel added documentation Improve documentation new feature PR that implements a new feature or capability in GMT add-changelog Add PR to the changelog labels Oct 12, 2023
@PaulWessel PaulWessel added this to the 6.5.0 milestone Oct 12, 2023
@PaulWessel PaulWessel self-assigned this Oct 12, 2023
@PaulWessel
Copy link
Member Author

Addendum: I do think these are needed:

  1. -Ms: Give an even number of tables, each pair of tables must have exactly N segments. N can vary between pairs tables. The segments k from the two files are juxtaposed and filled, for k = 1:N. Basically, OK to have many segments but pairwise organised in pairs of tables.
  2. -M modifier +llabel to enable adding filled rectangle to legend if -M+gfill was set. Without +l the item is not added to the legend. This is separate from -l which controls the primary fill as above.

@gd-a
Copy link
Contributor

gd-a commented Oct 12, 2023

Adresses #7869

@joa-quim
Copy link
Member

I find the rectangles in labels an over complication. All that is needed is line labels. Then what is above or bellow is obvious from the figure.

This is needed if one wants to place anything related to S1 in the legend.
@PaulWessel
Copy link
Member Author

You can always ignore the rectangles by plotting the lines separately. For those who do want filled rectangles in the legend they can, even both colours, via +lseclabel:

curve

Note I am only doing the black and green lines to show you can set them separately. Looks ugly to me but what do I know.

@joa-quim
Copy link
Member

What I mean is that with no more lines in the script we can lave a legend that says "lambda 1; lambda 2". It looks to me, and your mention to plotting the lines separately, that it cannot currently be done. Again, fine that some one wants to fill the legend space with useless information, but it shouldn't be the default.

@PaulWessel
Copy link
Member Author

Sure. Happy to hear what others think of defaults and legends. Better speak up now and have a chance to affect the final implementation or complain later on that it would have been better if...

@PaulWessel
Copy link
Member Author

What do you want it to be? You have full control over that. I should have guessed that comparing to zero or some other horizontal level is useful so I added +y[level] where the S1 comparison "dataset" is a constant, such as in the bottom plot below. Not sure why the amplitudes are different - probably something I did wrong.

nino

@joa-quim
Copy link
Member

Oops, forgot to hit the button yesterday.

For me this info in legend is all it needs to understand the plot.

And, as a side note, I find it a little buggy that GMT needs to be helped with --FORMAT_DATE_IN=yyyy/mm/dd. If we don't provide that it nearly guesses the time format.

C:\v>gmtinfo enso_new.txt
enso_new.txt: N = 1824  <1870-01-01T00:00:00/2021-01-01T00:00:00>       <-2.49/2.57>

C:\v>gmtinfo enso_new.txt --FORMAT_DATE_IN=yyyy/mm/dd
enso_new.txt: N = 1824  <1870-01-01T00:00:00/2021-12-01T00:00:00>       <-2.49/2.57>

GMTjl_j

@PaulWessel
Copy link
Member Author

Hm, I'll look at that gmtinfo issue. yyyy-mm-dd is the ISO standard I think but yours have the same order so ought to handle it I think.

You can get the legend you want by plotting with -M and color fills but no legend entries, then replot with pens and no fill and set the two legend entries.

@PaulWessel
Copy link
Member Author

Anything else missing from the implementation now that I added +y? @joa-quim ? @anbj ? @Esteban82 ?

@gd-a
Copy link
Contributor

gd-a commented Oct 13, 2023

I added +y[level] where the S1 comparison "dataset" is a constant

In that case we have two options :

  1. Like @joa-quim says, just the line to describe the plot (which would be incomplete, because there's 1 line and 2 colours).
  2. 1 file sends two legends "above constant" and "below constant".

@anbj
Copy link
Contributor

anbj commented Oct 13, 2023

Don't have a use case for this right now, so not much to contribute with in this discussion.
But looks very good!

@joa-quim
Copy link
Member

Like @joa-quim says, just the line to describe the plot (which would be incomplete, because there's 1 line and 2 colours).

Don't understand this comment. My plot clearly shows two lines with two colors. It was made with my GMT.jl function where I passed the legend as legend="enso,dmi". That is, two legends in one stroke.

You can get the legend you want by plotting with -M and color fills but no legend entries, then replot with pens and no fill and set the two legend entries.

A bit convoluted. And not to say that the legend with the squares needs to be longer. It has to say A > B & B < A not just A and B because the colored polygons are made up with the A and B lines.

@PaulWessel
Copy link
Member Author

Doable now I think? Use -l for one legend entry and -M+l for the other label. Or plot them as continuous lines with plot and add legends there. The rules currently in place say:

  1. If -Gfill is given and no -Wpen then we get a coloured rectangle showing color where S0 is above S1, with no outline
  2. If -Wpen is given and no -G then the pen is used to draw the upper section of the S0 line when it exceeds S1.
  3. If both are given then -G takes precedence for the legend entry

The same rules apply to -M (+gfill and +ppen) provided -M+llabel is set.

To me, your case would use the -M option with fill and no pens (or set the two pens equal for outline), then plot the two curves separately with your fill color as pen color and add -l for each line.

Question: Is the switching of pen color where S0 and S1 cross useful or useless?
Suggestion: If filling with color but showing a line with same color in the legend instead is the desirable, I could add a modifier that changes rule 3 to take pen color from the fill color and add line entry to legend?

@joa-quim
Copy link
Member

Have to go (classes).

@PaulWessel
Copy link
Member Author

We programmed GMT to handle any stupid date stamp format, even 2-digit years, month names, US order versus sane order. I understand it may be frustrating that yyyy/mm/dd is not parsed well when the default ISO format is yyyy-mm-dd but the fault there lies with data producers who dont follow conventions. Are we also going to build in special checks that detects that the month field exceeds 12 but never 31 and hence guess that it is mm/dd/yy? This would never end.

@gd-a
Copy link
Contributor

gd-a commented Oct 13, 2023

This would never end.

Weren't we talking about issuing warnings everywhere a few threads ago? 😛

@gd-a
Copy link
Contributor

gd-a commented Oct 13, 2023

@PaulWessel
Copy link
Member Author

This would never end.

Weren't we talking about issuing warnings everywhere a few threads ago? 😛

Maybe, but that would also never end. I cannot be our job to code up all these things just because people are no longer able to read instructions or store data in dumb formats.

@gd-a
Copy link
Contributor

gd-a commented Oct 13, 2023

I have to go too.
To wrap this up, I think your first PR + the constant are plenty enough. Other cases can be handled with not so complicated workarounds already available in the forum.
As for the legend, I would say that entry f(x1) is compared to f(x2)(which can be constant), thus the legend gets two entries:

  1. red : ˋf(x1)abovef(x2)`
  2. blue : f(x1) below `f(x2)ˋ

Option A (default):
Filled rectangle are enough (no border)

Option B:
No rectangle, just pen from x1, eventually x2 if desired and not a constant.
… except if you decide that the constant is automatically drawn too, which I think would be over complicating things compared to just call another « plot » command.

Option C:
If you fancy something really neat, then the rectangle’s top border of case 1 is pen from x1 and bottom border is pen from x2 (and vice versa for case 2).
^_ highly unnecessary, but fancy.

Have a good weekend !

@PaulWessel PaulWessel changed the title WIP Filling area between two time- or space-series Filling area between two time- or space-series Oct 13, 2023
@PaulWessel
Copy link
Member Author

I don't like indicating the fill of an area (between the two curves) but new modifier +r will (as the Julia examples) draw a line in the legend instead of the default filled rectangle. It replaces the pen color with the fill color though so this should be more than enough flexibility for version 1. I will make a doc/script illustration for inclusion in the plot RST documentation but I think this branch is good to go so I hvae removed the WIP.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 13, 2023

Summary of changed images

This is an auto-generated report of images that have changed on the DVC remote

Status Path
added doc/scripts/images/GMT_fill_curves.ps
modified doc/scripts/images/

Image diff(s)

Details

Added images

  • doc/scripts/images/GMT_fill_curves.png

Modified images

Path Old New

Report last updated at commit d5ae625

@PaulWessel PaulWessel merged commit d52c98b into master Oct 14, 2023
@PaulWessel PaulWessel deleted the curve-fill branch October 14, 2023 18:43
joa-quim added a commit that referenced this pull request Dec 14, 2023
maxrjones added a commit that referenced this pull request Jan 5, 2024
* Start 6.5 changelog

* Update changes.rst

* Add windbarbs reference

* Ref #7900

* Finish changelog for 6.5

---------

Co-authored-by: Paul Wessel <pwessel@hawaii.edu>
Co-authored-by: Joaquim <jluis@ualg.pt>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

add-changelog Add PR to the changelog documentation Improve documentation new feature PR that implements a new feature or capability in GMT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants