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

Different outcomes on specifying legends #1406

Closed
melodyjulia opened this issue Apr 1, 2024 · 18 comments
Closed

Different outcomes on specifying legends #1406

melodyjulia opened this issue Apr 1, 2024 · 18 comments

Comments

@melodyjulia
Copy link

melodyjulia commented Apr 1, 2024

I tried three ways to specify legend, but got three different appearances.

First:

x = collect(1:10)
gmtbegin()
    basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a)
    lines(x,sin.(x),legend="sin(x)")
    lines(x,cos.(x),legend="cos(x)")
    legend(fontsize=6,position=(inside="RT",width=1.5))
gmtend(:show)

Second:

x = collect(1:10)
basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a)
lines!(x,sin.(x),legend="sin(x)")
lines!(x,cos.(x),legend="cos(x)")
legend!(fontsize=6,position=(inside="RT",width=1.5), show=true)

Third:

x = collect(1:10)
basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a)
lines!(x,sin.(x),legend="sin(x)")
lines!(x,cos.(x),legend=(label="cos(x)",fontsize=6,position=(inside="RT",width=1.5)), show=true)

The first way gives warning as

Warning: the following options were not consumed in legend => [:fontsize]

The second way gives warning as

pslegend [WARNING]: File <stdin> is empty!

Only the third method can set correct font size for the labels in legend.

BTW, the appearance of the figure produced by the first method is very different from that from the other two methods, it seems they use different settings.

first second third
@joa-quim
Copy link
Member

joa-quim commented Apr 1, 2024

The answer tho those goes back into GMT itself. In GMT (not the wrapper) we have the classic mode and the modern mode (man pages explain in depth the differences). In GMT.jl whenever we directly use gmtbegin or indirectly subplot and inset we are using GMT's modern mode and it has its own set of defaults. For example it annotates all 4 sides. The legend option inside the plotting modules of a modern mode (-l in plain GMT) is a wrapper of the legend module and intends to greatly simplify its usage.

On the other hand, in GMT.jl most of cases (those that do not use gmtbegin) use a kind of re-implementation of the modern mode but in plain Julia. The settings are not exactly equal (default annotates 2 sides and axes line thicknesses are a bit thinner. The legend option (not the module) is also less powerful and sometimes has difficulties in finding the true string length (a difficult problem that GMT only solves inside the PostScript language).

So, maybe a can fix that, but in your first example you should control the font size as mentioned in the legend manual. That is

legend(par=(FONT_ANNOT_PRIMARY=6,), position=(inside="RT",width=1.5))

The second case is more obscure for me now. For me on Windows that example (the legend command) actually hangs Julia. I need to find out what is happening in this case. It's weird because a much more complex example shown in its man page works fine.

Basically, I do not use much the gmtbegin/gmtend construct and the default have remain a bit different. I may be able to change that in a clean way, but it needs investigation.

@melodyjulia
Copy link
Author

Thanks for your explanation.
Although the third way works, but it seems the second way is more syntax friendly and clear.

@joa-quim
Copy link
Member

joa-quim commented Apr 3, 2024

If you try the master version case 1 is solved (now looks like 3).
Case 2 is harder and I don't even understand how you could get a result. The point/confusion here is that legend is more than one thing. It is a module in itself, which is wrapped in modern mode by the legend option. This is the most versatile of all legend options. But legend is also an option for the plot family modules. In this case the number of possibilities is more reduced.

In you case 2 example you are calling legend in non-modern mode but passing no input data and that is why it complains that stdin is empty. For me on Windows that hangs Julia.

But with some convoluted gymnastics I made case 2 work too (also in master only for now) as long as it's called as legend! and previous commands had added entries to the legend fields (like your cases 2 & 3 do). Please try it.

@melodyjulia
Copy link
Author

melodyjulia commented Apr 5, 2024

This is awesome! I can understand the complexity of legend now.

Using the master version, the figure of the first case has no labels for tick marks.
first

For the second case, the font size of legend labels cannot be set, neither of the following two ways work:

x = collect(1:10)
basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a,title="Second")
lines!(x,sin.(x),legend="sin(x)")
lines!(x,cos.(x),legend="cos(x)")
legend!(fontsize=3,position=(inside="RT",width=1.5),show=true)
x = collect(1:10)
basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a,title="Second")
lines!(x,sin.(x),legend="sin(x)")
lines!(x,cos.(x),legend="cos(x)")
legend!(par=(FONT_ANNOT_PRIMARY=3,),position=(inside="RT",width=1.5),show=true)

In addition, I noticed a minor issue on showing figure in the case 3, the following two methods showing figure produce different font sizes in the label of legend:

x = collect(1:10)
basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a,title="Third (show=true)")
lines!(x,sin.(x),legend="sin(x)")
lines!(x,cos.(x),legend=(label="cos(x)",fontsize=4,position=(inside="RT",width=1.5)),show=true)
x = collect(1:10)
basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a,title="Third (showfig)")
lines!(x,sin.(x),legend="sin(x)")
lines!(x,cos.(x),legend=(label="cos(x)",fontsize=4,position=(inside="RT",width=1.5)))
showfig()

Btw, the settings used by GMT.jl are more modern in my opinion, especially the thinner axes lines.

third1 third2

@joa-quim
Copy link
Member

joa-quim commented Apr 5, 2024

Hm, I can confirm the second issue but not the first. For me it plots the annotations. I don't see what it wouldn't as that is explicitly set in basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a)

@melodyjulia
Copy link
Author

This is weird. It can be reproduced under both Linux and macOS with the master version. Is there any way I could output more information for diagnostic?

@joa-quim
Copy link
Member

joa-quim commented Apr 6, 2024

You can add V=true options in each command to have GMT print information, or even V=:d for debug messages but that is very verbose. When I add V=true in basemap I see:

basemap [INFORMATION]: Constructing the basemap
basemap [INFORMATION]: Linear projection implies y-axis distance exaggeration relative to the x-axis by a factor of 3
basemap [INFORMATION]: Auto-frame interval for x-axis (item 0): a2f2
basemap [INFORMATION]: Auto-frame interval for y-axis (item 0): a0.5f0.5
basemap [INFORMATION]: Map scale is 0.0015 km per cm or 1:150.

You can also add MAP_FRAME_TYPE="inside" like bellow to see if the annotations show up inside the frame

basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a, par=(MAP_FRAME_TYPE="inside",))

@joa-quim
Copy link
Member

joa-quim commented Apr 6, 2024

Indeed strange. It works for me on WSL too.

@melodyjulia
Copy link
Author

melodyjulia commented Apr 6, 2024

I tried the following code snippet:

x = collect(1:10)
gmtbegin()
    basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a,title="First",V=true)
    lines(x,sin.(x),legend="sin(x)")
    lines(x,cos.(x),legend="cos(x)")
    legend(fontsize=6,position=(inside="RT",width=1.5))
gmtend(:show)

If running it in Julia REPL, it works and plots the annotations.

But if running it in Jupyter notebook, it doesn't work and outputs:

basemap [INFORMATION]: GMT_Parse_Options: Interval-setting -B options were reordered to appear before axis and frame -B options to ensure proper parsing.
basemap [INFORMATION]: GMT_Parse_Options: New option order: -R1[/10/-1/1](http:https://localhost:8888/10/-1/1) -JX6[/4](http:https://localhost:8888/4) -V -Ba -B+tFirst
basemap [INFORMATION]: Constructing the basemap
basemap [INFORMATION]: Linear projection implies y-axis distance exaggeration relative to the x-axis by a factor of 3
basemap [INFORMATION]: Auto-frame interval for x-axis (item 0): a2f2
basemap [INFORMATION]: Auto-frame interval for y-axis (item 0): a0.5f0.5
basemap [INFORMATION]: Map scale is 0.0015 km per cm or 1:150.
basemap [INFORMATION]: You should specify a paper size when requesting a PostScript file.
basemap [INFORMATION]: Changing paper size to A4, but we cannot know if this is adequate for your plot; better to use PS_MEDIA explicitly.

@joa-quim
Copy link
Member

joa-quim commented Apr 6, 2024

Yes, can confirm this too. The reason lies on what caused this messages to print

basemap [INFORMATION]: You should specify a paper size when requesting a PostScript file.
basemap [INFORMATION]: Changing paper size to A4, but we cannot know if this is adequate for your plot; better to use PS_MEDIA explicitly.

This makes no sense because we are not asking for a PS (PostScript) output, but somehow that request is sneaking in.

And, BTW, the showfig() issue is hopefully solved in master.

@melodyjulia
Copy link
Author

Thanks very much! I tested with the master version and the showfig() issue is gone.

@joa-quim
Copy link
Member

joa-quim commented Apr 8, 2024

I hope I've solved the First issue too, but this guy proved to be much more tricky than anticipated so side effects may arise.
In master too.

@melodyjulia
Copy link
Author

It works in the master version now! Cheers!

@joa-quim
Copy link
Member

joa-quim commented Apr 8, 2024

Released that all in 1.12.2

@melodyjulia
Copy link
Author

I've tested with 1.12.2, all above cases are handled charmingly except for setting font size for legend label via the following two ways:

x = collect(1:10)
basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a,title="Second")
lines!(x,sin.(x),legend="sin(x)")
lines!(x,cos.(x),legend="cos(x)")
legend!(fontsize=3,position=(inside="RT",width=1.5))
showfig()

and

x = collect(1:10)
basemap(limits=(1,10,-1,1),figsize=(6,4),frame=:a,title="Second")
lines!(x,sin.(x),legend="sin(x)")
lines!(x,cos.(x),legend="cos(x)")
legend!(par=(FONT_ANNOT_PRIMARY=3,),position=(inside="RT",width=1.5))
showfig()

@joa-quim
Copy link
Member

It was not only the font size that could not be changed but all parameters set in the legend!(...) call. Again, tentatively fixed in master. But note that the par=(FONT_ANNOT_PRIMARY=3,) form is not supported here.

@melodyjulia
Copy link
Author

Thanks. It works now! The legend!(...) call is really cool!

@joa-quim
Copy link
Member

All solved, I think.

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

No branches or pull requests

2 participants