Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable -l<label> auto-legend in plot #1749

Merged
merged 40 commits into from
Oct 10, 2019
Merged

Enable -l<label> auto-legend in plot #1749

merged 40 commits into from
Oct 10, 2019

Conversation

PaulWessel
Copy link
Member

When plotting plain symbols with known size and color/pen we can automatically build a legend file via -l[label] in plot. Only applies to modern mode. Not documented yet. May or may not go into 6.0 or master but seems straightforward.

When plotting plain symbols with known size and color/pen we can automatically build a legend file via -l in plot.  Only applies to modern mode.  Not documented yet.
If only lines are plotted with no symbol size then default to 0.5 cm.
@PaulWessel
Copy link
Member Author

I think the plot/legend auto-labeling is simple enough to add to 6.0.0 even if a new feature. Here is an example script that plots a table three times with lines and different symbols and using the -llabel option to build up an automatic label info file. Since legend is not given a legend file it looks to see if there is a hidden one. I implemented this the same way we do CPT so there may be one legend per scope (figure, subplot, etc):

gmt begin plot png
  gmt plot -R0/7/3/7 -Jx1i -B @Table_5_11.txt -Sc0.15i -Glightgreen -Wfaint -lApples
  gmt plot @Table_5_11.txt -W1.5p,gray -l"My Lines"
  gmt plot @Table_5_11.txt -St0.15i -Gorange -lOranges
  gmt legend -DjTR+w1.15i+o0.1i -F+p1p
gmt end show

which gives this plot:

plot

What do you think, @GenericMappingTools/core? There are a few unresolved issues:

While the given symbol sizes are used to build the legend, a line is not specified with a size in plot. I assign lines the same symbol size as the max symbol size given to other items n the legend. If there are only lines then I default to 0.5 cm.
Users might be interested in getting their mittens on this auto-legend file and improve it. How would we do that (it is gone with the session).

Enable vertical lines, gaps, and font selection.
Must match uppercase codes in pslegend. Also add to cookbook.
Add doc script showing autolegend and add to cookbook.
@PaulWessel
Copy link
Member Author

Update: I have completed the implementation of -l. There are modifier support for drawing horizontal (+d) and vertical (+v) lines, add a gap (+g), change the number of columns (+n), and set a header (+h). You will note these lower-case modifiers correspond to the upper-case legend codes in pslegend. In addition there is a way to specify the font (+f) and override the symbol size (or set line length) via +s. Documentation has been updated, new test and doc script added. What remains is to use this in a few of our gallery examples.

These were perfect examples of using -l to generate legend data. Slight differences required an update to the two PS files.
@PaulWessel
Copy link
Member Author

Now examples 3 and 7 use auto-legends. Examples 42 and 49 cannot since they are doing more complicated legends. Please give this a try, @seisman and @joa-quim.

@joa-quim
Copy link
Member

joa-quim commented Oct 6, 2019

We need also a flag to positioning the legend in the figure.

@PaulWessel
Copy link
Member Author

That is what legend does, at the end.

@PaulWessel
Copy link
Member Author

I am guessing you mean one should not have to call legend at the end? We could contemplate that with some basic defaults. But I dont think we want to replicate all the options in gmt legend that pertains to placement, width, justification, outline, shade, line-spacing, etc. etc. We might be able to guesstimate a suitable legend box width from the strings, then slap a white box in the TR corner.

@joa-quim
Copy link
Member

joa-quim commented Oct 6, 2019

Yes. Once -l is used it's clear that a legend is required. So if gmt legend is not called a default call should come out. And a +p<LRCTMB> to select position would be handy too.

@PaulWessel
Copy link
Member Author

Probably should be +jjust [TR]. So this means gmt end, as it loops over all the figures, need to check if there is a legend file for that scope and that it has not yet been used for this figure. if so, it needs to guesstimate a width from the longest text label plus space for symbol and gaps, get the +jjust setting from a comment in the legend file, and then call legend, maybe with some small offset from the toner via +o, maybe 1-2 % of map dimensions?

@PaulWessel
Copy link
Member Author

Well, it is more complicated: When an inset or a subplot panel calls inset end or subplot end, we need to do the same thing: was there a legend file created that was not used, and if so call gmt legend here as well. Then for all figures as well. The legend spec files can appear for insets, subplot panels, figures, and session (one figure).

Now, when legend is called and there is no input file and a hidden legend file is found, we use it and then delete it.  THus, when gmt inset end, gmt subplot end, or gmt end come along and find a legend file it means legend was not called explicitly.  If so, we add a call to legend with a few default settings.
@PaulWessel
Copy link
Member Author

I gotta go teach etc but I have added support for automatically plotting the legend if no legend call is made and a legend file is found (because of -l options). I tested the case above which works. it would be great if someone could make examples like the above with subplots and insets so that I can test if they work as well [not tested so far].

@PaulWessel
Copy link
Member Author

Never mind, the subplot works fine.

@PaulWessel
Copy link
Member Author

Looks like things are working. Please try to break it. Subplot:

gmt begin two pdf
  gmt subplot begin 2x1 -Fs7i/3i
    gmt plot -R0/7/3/7 -B @Table_5_11.txt -Sc0.15i -Glightgreen -Wfaint -lApples+hLEGEND+f16p+d -c0
    gmt plot @Table_5_11.txt -W1.5p,gray -l"My Lines"
    gmt plot @Table_5_11.txt -St0.15i -Gorange -lOranges
    gmt plot -R0/7/3/7 -B @Table_5_11.txt -Sc0.15i -Glightgreen -Wfaint -lApples+hLEGEND+f16p+d -c1
    gmt plot @Table_5_11.txt -W1.5p,gray -l"My Lines"
    gmt plot @Table_5_11.txt -St0.15i -Gred -lRed
  gmt subplot end
gmt end show

Inset:

gmt begin inset pdf
  gmt psbasemap -R0/7/3/7 -Jx1i -B0
  gmt inset begin -DjTR+w3i/2i
    gmt plot -R0/7/3/7 -B @Table_5_11.txt -Sc0.15i -Glightgreen -Wfaint -lApples+hLEGEND+f16p+d
    gmt plot @Table_5_11.txt -W1.5p,gray -l"My Lines"
    gmt plot @Table_5_11.txt -St0.15i -Gorange -lOranges
  gmt inset end
gmt end show

@joa-quim
Copy link
Member

joa-quim commented Oct 7, 2019

Not about the legend, but shouldn't the inset E & N annotations be trimmed?

@joa-quim
Copy link
Member

joa-quim commented Oct 7, 2019

-l+s changes size, but it's a constant size, whilst the symbols in the plot may have different sizes. +s<scale> would be more handy (maintain symbols proportionality)

@PaulWessel
Copy link
Member Author

Your first question is I was lazy and did not add margin space with -M.

Second question is good, maybe we want it to be an overall scaling instead of a fixed size. The problem I was trying to solve was the "size" of lines which are undefined. So we could say if size is zero (line) then set to this size, else if size is > 0 then scale.

@PaulWessel
Copy link
Member Author

But your first also begs the question if gmt inset begin should turn on a clip path, to be undone when gmt inset ends comes along. Should it?

@PaulWessel
Copy link
Member Author

Or should gmt inset begin have option -C for clip on [off]?

@PaulWessel
Copy link
Member Author

Or reverse (like pstext), have -N for no clip [clip]?

@seisman
Copy link
Member

seisman commented Oct 10, 2019

Doesn't work well with short labels.

#!/bin/bash
cat > abc.txt << EOF
1 1
2 2
3 3
4 4
EOF

gmt begin map
gmt basemap -R0/5/0/5 -JX10c -Baf
gmt plot abc.txt -Sc0.2c -lABC
gmt plot abc.txt -St0.2c -lDEF
gmt end show

image

@seisman
Copy link
Member

seisman commented Oct 10, 2019

+f doesn't work:

#!/bin/bash
cat > abc.txt << EOF
1 1
2 2
3 3
4 4
EOF

gmt begin map png
gmt basemap -R0/5/0/5 -JX10c -Baf
gmt plot abc.txt -Sc0.2c -lApple+f9p,1,blue
gmt plot abc.txt -St0.2c -lOrange+f9p,1,red
gmt end show

@seisman
Copy link
Member

seisman commented Oct 10, 2019

+n works but the legend with is not correctly set.

#!/bin/bash
cat > abc.txt << EOF
1 1
2 2
3 3
4 4
EOF

gmt begin map png
gmt basemap -R0/5/0/5 -JX10c -Baf
gmt plot abc.txt -Sc0.2c -lApple+n2
gmt plot abc.txt -St0.2c -lOrange
gmt end show

@seisman
Copy link
Member

seisman commented Oct 10, 2019

When plotting large symbols, we usually need a larger line-spacing (i.e. gmt legend -D+l2.0). Maybe we need another modifier to specify the line-spacing factor? See the script below to reproduce the issue:

#!/bin/bash
cat > abc.txt << EOF
1 1
2 2
3 3
4 4
EOF

gmt begin map png
gmt basemap -R0/5/0/5 -JX10c -Baf
gmt plot abc.txt -Sc0.75c -lApple
gmt plot abc.txt -St0.75c -lOrange
gmt end show

@seisman
Copy link
Member

seisman commented Oct 10, 2019

use **+l** to specify the length of a line symbol
use **+s** to override the size of the current symbol for the legend or set a length if plotting a line or contour

It seems there are two ways to set the length of a line. What's the difference?

@PaulWessel
Copy link
Member Author

Hm, yes I guess we could eliminate +l. This has gone back and forth... OK, will stick with +s to set a fixed dimension of a symbol, including a line segment length.

@seisman
Copy link
Member

seisman commented Oct 10, 2019

Hm, yes I guess we could eliminate +l. This has gone back and forth... OK, will stick with +s to set a fixed dimension of a symbol, including a line segment length.

Please also see my comments above. We may use +l for setting the line spacing.

+s probably doesn't set the line length correctly. In the following script, I expect to have a 1-cm line, but the lines seems much longer than 1 cm.

#!/bin/bash
cat > abc.txt << EOF
1 1
2 2
3 3
4 4
EOF

gmt begin map png
gmt basemap -R0/5/0/5 -JX5c -Baf
gmt plot abc.txt -Sc0.2c -lApple
gmt plot abc.txt -St0.2c -lOrange
gmt plot abc.txt -W1p,blue -lLines+s1c
gmt end show

@PaulWessel
Copy link
Member Author

Regarding larger line spacing: The actual line spacing is determined by two times: the current annotation font and the line scaling [1.1]. Normally, if you really wanted to do large symbols bigger than your annotation font you would either change the font (you may be making a large wall map so that makes sense) or you mess with +lspacing in pslegend. We could add +lspacing for this since the current line length can be absorbed by +s. However, pretty sure we will get calls for adding +wwidth too since the auto-width cannot be perfect until I code all that up in PostScript itself. I think we will need to do that at some point. The only time one would need to specify a width is when setting paragraphs since they need to wrap at the end of the line. So legend -D...+w can probably never go away but can be optional for the cases without a paragraph of text (most cases). Same with -l. So we will need +w as well for now since I cannot compute a proper width that will work for any font.

Line length is now set by +s as for other symbols. Legend width can be hard-wired via +w.
@PaulWessel
Copy link
Member Author

I removed +l (for now) so line length is also set with +s. I added +w to set legend width. That is the only cure for your short legend labels above. Try adding +w1.6c to your "A" label option.

@seisman
Copy link
Member

seisman commented Oct 10, 2019

+s and +w now works for me. +f still can't change the label font. As for +n2, it works if I give a legend width manually, but I expect to see a more reasonable guess of the legend width (maybe multiple current legend width by 2 if +n2 is used).

Did not make it into the legends file.
@PaulWessel
Copy link
Member Author

Did not actually use +n to scale the width - now does. But only if +n is given on the first -l. If used later it simply sub-divides the available space set at the start.
The +f only applies to the header font since that is how H works. I did not implement the label code L (as +l, but could) and it also takes a font so could use +f. But for the regular label strings they are using annotation font (same in legend).

@seisman
Copy link
Member

seisman commented Oct 10, 2019

use +f to set the font to use for title or labels

It's a little misleading here. I though it sets the font of "H headers" and "regular label strings".

@joa-quim
Copy link
Member

We normally don't those to have the same font size, so hardly the same flag.

@PaulWessel
Copy link
Member Author

I will clarify what +f does in the docs.

Copy link
Member

@seisman seisman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-l looks good to me.

@PaulWessel
Copy link
Member Author

I think perhaps we should add a beta warning in the -l instructions since this is so fresh that we may wish to break some compatibility as we learn more of its use?

@PaulWessel PaulWessel changed the title WIP Enable -l<label> auto-legend in plot Enable -l<label> auto-legend in plot Oct 10, 2019
@PaulWessel PaulWessel merged commit b44e4be into 6.0 Oct 10, 2019
@PaulWessel PaulWessel deleted the activateautolegend branch October 10, 2019 19:32
@seisman seisman mentioned this pull request Oct 12, 2019
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants