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

Multiple legend columns #2603

Closed
De-Guo opened this issue Jul 12, 2023 · 4 comments
Closed

Multiple legend columns #2603

De-Guo opened this issue Jul 12, 2023 · 4 comments
Labels
feature request New feature wanted

Comments

@De-Guo
Copy link

De-Guo commented Jul 12, 2023

Description of the desired feature

PyGMT does not support displaying legends in multiple columns, which is usually used when the items to plot have a large number. For instance, the following script would show the legend in two columns.

import pygmt

fig = pygmt.Figure()

fig.basemap(projection="x2c", region=[0, 7, 3, 7], frame=True)

fig.plot(
    data="@Table_5_11.txt",
    style="c0.40c",
    fill="lightgreen",
    pen="faint",
    label="Apples",
)
fig.plot(data="@Table_5_11.txt", pen="1.5p,gray", label="My lines")
fig.plot(data="@Table_5_11.txt", style="t0.40c", fill="orange", label="Oranges")

fig.legend(position="JTR+jTR+o0.2c", box=True, N=2)

fig.show()

Are you willing to help implement and maintain this feature?

No

@De-Guo De-Guo added the feature request New feature wanted label Jul 12, 2023
@yvonnefroehlich
Copy link
Member

yvonnefroehlich commented Jul 12, 2023

I agree that it would be nice to be able to specify the number of columns directly via the Figure.legend method. As far as I know for auto-legends in GMT, the number of columns cannot be specified and it is always 1.

For a legend with multiple columns, users have to write a specific input file instead of using the label parameter of the single plotting methods. For details on the Legend Codes, please see the upstream GMT documentation at https://docs.generic-mapping-tools.org/6.4/legend.html#legend-codes. To get multiple columns, add N number_of_columns at the top of the file.
Legend file: legend_horizontal.txt

N 3

S 0.4c c 0.5 lightgreen 0.5p,black 1c Apples
S 0.4c - 0.5 gray 1.5p,gray 1c My Lines
S 0.4c t 0.5 orange 0.5p,black 1c Oranges

This file is passed to the spec parameter of the Figure.legend method. For legends with multiple columns, users have to state the width of the legend via the position parameter (+w).
Code example:

fig = pygmt.Figure()

fig.basemap(projection="x2c", region=[0, 7, 3, 7], frame=True)

fig.plot(
    data="@Table_5_11.txt",
    style="c0.40c",
    fill="lightgreen",
    pen="faint",
   # label="Apples",
)
fig.plot(data="@Table_5_11.txt", pen="1.5p,gray") # label="My lines"
fig.plot(data="@Table_5_11.txt", style="t0.40c", fill="orange") # label="Oranges"

fig.legend(spec="legend_horizontal.txt", position="JTR+jTR+w7.5c+o0.2c", box=True)

fig.show()
# fig.savefig(fname="legend_horizontal.png")

Output figure:
legend_horizontal

@De-Guo
Copy link
Author

De-Guo commented Jul 13, 2023

Thanks,this works at present.

@De-Guo De-Guo closed this as completed Jul 13, 2023
@weiji14
Copy link
Member

weiji14 commented Jul 13, 2023

I agree that it would be nice to be able to specify the number of columns directly via the Figure.legend method. As far as I know for auto-legends in GMT, the number of columns cannot be specified and it is always 1.

For auto legend, yes, only one column is supported I think.

For legend with multiple columns, users have to write a specific input file instead of using the label parameter of the single plotting methods. For details on the Legend Codes, please see the upstream GMT documentation at https://docs.generic-mapping-tools.org/6.4/legend.html#legend-codes. To get multiple columns, add N number_of_columns at the top of the file. Legend file: legend_horizontal.txt

There was a suggestion to allow fig.legend's spec parameter accept StringIO inputs (see #571) that would make it easier to generate these legend.txt files on the fly, and a working proof of concept at #576. We could potentially revive that if there's interest.

@yvonnefroehlich
Copy link
Member

I was wrong, it's possible to create multi-column legends for auto-legends. I though there should be a modifier for legend to force a multi-column legend, but the specification has to be made together with the argument passed to the label parameter of plot. (See also the GMT forum https://forum.generic-mapping-tools.org/t/horizontal-legend/4362/3?u=yvonnefroehlich.)

# Based on Gallery example: https://www.pygmt.org/latest/gallery/embellishments/legend.html#sphx-glr-gallery-embellishments-legend-py
# Last acces: 2023/10/20

import pygmt

fig = pygmt.Figure()

# -----------------------------------------------------------------------------
# Left: Vertical (one column) legend
fig.basemap(projection="x2c", region=[0, 7, 3, 7], frame=True)

fig.plot(
    data="@Table_5_11.txt",
    style="c0.40c",
    fill="lightgreen",
    pen="faint",
    label="Apples",
)
fig.plot(data="@Table_5_11.txt", pen="1.5p,gray", label="My lines")
fig.plot(data="@Table_5_11.txt", style="t0.40c", fill="orange", label="Oranges")

fig.legend(position="JTR+jTR+o0.2c", box=True)

fig.shift_origin(xshift="+w1c")

# -----------------------------------------------------------------------------
# Right: Horizontal (three columns) legend
fig.basemap(projection="x2c", region=[0, 7, 3, 7], frame=True)

fig.plot(
    data="@Table_5_11.txt",
    style="c0.40c",
    fill="lightgreen",
    pen="faint",
    # +N sets columns of the legend corresponding to the given number
    label="Apples+N3",
)
fig.plot(data="@Table_5_11.txt", pen="1.5p,gray", label="My lines")
fig.plot(data="@Table_5_11.txt", style="t0.40c", fill="orange", label="Oranges")

# For multi-column legends users have to provide the width via +w
fig.legend(position="JTR+jTR+w7c+o0.2c", box=True)

fig.show()

# fig.savefig(fname="multi_col_legend.png")

Output figure:
multi_col_legend

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature wanted
Projects
None yet
Development

No branches or pull requests

3 participants