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

Figure.text(): Support paragraph mode #1078

Open
yebo-liu opened this issue Mar 19, 2021 · 14 comments
Open

Figure.text(): Support paragraph mode #1078

yebo-liu opened this issue Mar 19, 2021 · 14 comments
Labels
feature request New feature wanted good first issue Good for newcomers help wanted Helping hands are appreciated

Comments

@yebo-liu
Copy link

Description of the desired feature
I was trying to place some texts on my plot. The texts are quite long and require to be separated into paragraphs. Maybe I got something wrong, but it looks like the paragraph mode of gmt hasn't been wrapped in pygmt yet?

Are you willing to help implement and maintain this feature? Yes/No

@yebo-liu yebo-liu added the feature request New feature wanted label Mar 19, 2021
@welcome
Copy link

welcome bot commented Mar 19, 2021

👋 Thanks for opening your first issue here! Please make sure you filled out the template with as much detail as possible. You might also want to take a look at our contributing guidelines and code of conduct.

@weiji14
Copy link
Member

weiji14 commented Mar 19, 2021

Hi @yebo-liu, could you provide an example of your PyGMT script and the text that you want to plot? Are you trying to plot the text using fig.text, or in fig.legend, or somewhere else?

@yebo-liu
Copy link
Author

Hi @weiji14 , thanks for the prompt reply. Please see below

fig = pygmt.Figure()
fig.basemap(projection="W0/12i", region="g", frame=['30g30'],transparency=70)
fig.text(text='long texts',x=90,y=0,font='10p')
fig.show()

image

I'm not really familiar with PyGMT nor GMT. What I'm trying to achieve is that to get the texts change lines and break it into more than one paragraph if possible. Hopefully I made myself clear.

@weiji14
Copy link
Member

weiji14 commented Mar 19, 2021

Ok, I won't be able to reply for the next few hours, but maybe someone else can chip in.

There was some work on supporting long titles in fig.basemap at GenericMappingTools/gmt#4562 (but that will be available in GMT 6.2.0, not the current 6.1.1). Alternatively, there might be a way to hack out a solution using fig.legend (see https://docs.generic-mapping-tools.org/6.1/gallery/ex22.html). Is your long paragraph meant to be a sort of description of the map? Or more of a title description? Just want to help you figure out the best solution here.

@seisman
Copy link
Member

seisman commented Mar 19, 2021

@yebo-liu I believe it would be very trick to have a Pythonic way to support paragraph mode. Here is an PyGMT example modified from the official text manual (https://docs.generic-mapping-tools.org/dev/text.html#examples). The key points are:

  • You have to prepare a plaintext following the text manpage
  • Use M=True when calling Figure.text()
import pygmt

with open("text.txt", "w") as fp:
    fp.write('''\
> 0 0 13p 3i j
@%5%Figure 1.@%% This illustration shows nothing useful, but it still needs
a figure caption. Highlighted in @;255/0/0;red@;; you can see the locations
of cities where it is @\_impossible@\_ to get any good Thai food; these are to be avoided.
''')

fig = pygmt.Figure()
fig.basemap(projection="W0/12i", region="g", frame=['30g30'])
fig.text(textfiles="text.txt", font='10p', M=True)
fig.show()

@yebo-liu
Copy link
Author

Thanks @seisman and @weiji14 for your help. Your solutions solved my problem.

@seisman seisman reopened this Mar 19, 2021
@seisman
Copy link
Member

seisman commented Mar 19, 2021

Reopen the issue as it's a useful feature.

@seisman seisman changed the title paragraph mode in pygmt Let Figure.text() support paragraph mode Mar 20, 2021
@seisman
Copy link
Member

seisman commented Mar 20, 2021

This feature is not that hard to implement as I expected. The key here is the -M option (https://docs.generic-mapping-tools.org/dev/text.html#m):

Paragraph mode. Files must be multiple segment files. Segments are separated by a special record whose first character must be flag [Default is >]. Starting in the 3rd field, we expect to find information pertaining to the typesetting of a text paragraph (the remaining lines until next segment header). The information expected is (x y [font angle justify] linespace parwidth parjust), where x y font angle justify are defined above (font, angle, and justify can be set via -F), while linespace and parwidth are the linespacing and paragraph width, respectively. The justification of the text paragraph is governed by parjust which may be l(eft), c(enter), r(ight), or j(ustified). The segment header is followed by one or more lines with paragraph text. Text may contain the escape sequences discussed above, although composite characters are not supported. Separate paragraphs with a blank line. Note that here, the justification set via -F+j applies to the box alignment since the text justification is set by parjust. Note: cannot be used with LaTeX expressions.

To support paragraph mode, we need to prepare a file like this one.

> x y [font angle justify] linespace parwidth parjust
This is a long paragraph to show on figures.

Figure.text() already has parameters for x, y, font, angle, and justify, so the only thing we need to do is providing parameters for linespace, parwidth and parjust.

There are two possible syntax:
1.

import pygmt
fig = pygmt.Figure()
fig.basemap(region=[0, 10, 0, 10], projection="X10c/10c", frame=True)
fig.text(
    x=2, y=2, font="15p", angle=30, justify="TL", 
    text="This is a very long paragraph and should be in multiple lines",
    paragraph={
        "linespace": "13p"
        "width": "10c",
        "justify": "l" 
    }
)
fig.show()
import pygmt
fig = pygmt.Figure()
fig.basemap(region=[0, 10, 0, 10], projection="X10c/10c", frame=True)
fig.text(
    x=2, y=2, font="15p", angle=30, justify="TL", 
    text="This is a very long paragraph and should be in multiple lines",
    paragraph_linespace="13p",
    paragraph_width="10c",
    paragraph_justify="l",
)
fig.show()

It's even possible to automatically detect and apply paragraph mode when a text string containing line breaks are passed, for example, "This is a long paragrapn\nThis is a newline\nThis is another line".

@munzekm
Copy link

munzekm commented Apr 2, 2021

Hello! Me and my team of developers would like to know if this issue is still open to contribute to? We currently just worked on pull request #1070 and we would like to continue to work on this open source project for our software innovation class. @noorbuchi @cklima616 @nathandloria

@seisman
Copy link
Member

seisman commented Apr 3, 2021

@munzekm Thanks for your interest in this feature. I'm afraid this issue needs more discussion before someone tries to work on it.

@noorbuchi
Copy link
Contributor

@seisman do you have any suggestions for a feature/documentation/fix that our group could work on. Maybe something that has already been discussed. Please let us know. Thanks!

@weiji14
Copy link
Member

weiji14 commented Apr 6, 2021

May I suggest #549 which is a tutorial for datetime inputs?

@noorbuchi
Copy link
Contributor

@weiji14 thanks for the suggestion! we're currently taking a look at it.

@weiji14 weiji14 added the help wanted Helping hands are appreciated label Jun 6, 2021
@weiji14 weiji14 added this to the 0.6.0 milestone Oct 29, 2021
@weiji14 weiji14 added this to To do in Pythonic GMT arguments via automation Oct 29, 2021
@weiji14
Copy link
Member

weiji14 commented Oct 29, 2021

This feature is not that hard to implement as I expected. The key here is the -M option (https://docs.generic-mapping-tools.org/dev/text.html#m):

Figure.text() already has parameters for x, y, font, angle, and justify, so the only thing we need to do is providing parameters for linespace, parwidth and parjust.

There are two possible syntax:
1.

import pygmt
fig = pygmt.Figure()
fig.basemap(region=[0, 10, 0, 10], projection="X10c/10c", frame=True)
fig.text(
    x=2, y=2, font="15p", angle=30, justify="TL", 
    text="This is a very long paragraph and should be in multiple lines",
    paragraph={
        "linespace": "13p"
        "width": "10c",
        "justify": "l" 
    }
)
fig.show()
import pygmt
fig = pygmt.Figure()
fig.basemap(region=[0, 10, 0, 10], projection="X10c/10c", frame=True)
fig.text(
    x=2, y=2, font="15p", angle=30, justify="TL", 
    text="This is a very long paragraph and should be in multiple lines",
    paragraph_linespace="13p",
    paragraph_width="10c",
    paragraph_justify="l",
)
fig.show()

It's even possible to automatically detect and apply paragraph mode when a text string containing line breaks are passed, for example, "This is a long paragrapn\nThis is a newline\nThis is another line".

I would prefer the 2nd functional parameter option since it can be tab-completed, but this also relates to #1082 on whether we should use dictionary/functional/classes for these sort of parameters. For this text 'paragraph' feature, the functional style might be ok since it's a one-off thing that won't be reused in other PyGMT functions. But maybe someone has another idea?

Anyways, to resolve this issue, we'll need to 1) alias M = "paragraph"; 2) handle the linespace/width/justify parsing; and 3) add a gallery example on how text paragraphs can be plotted.

@weiji14 weiji14 added the good first issue Good for newcomers label Nov 8, 2021
@weiji14 weiji14 modified the milestones: 0.6.0, 0.7.0 Mar 1, 2022
@seisman seisman modified the milestones: 0.7.0, 0.8.0 Jun 17, 2022
@seisman seisman removed this from the 0.8.0 milestone Dec 11, 2022
@seisman seisman added this to the 0.9.0 milestone Dec 11, 2022
@seisman seisman modified the milestones: 0.9.0, 0.10.0 Mar 16, 2023
@weiji14 weiji14 removed this from the 0.10.0 milestone Aug 24, 2023
@seisman seisman changed the title Let Figure.text() support paragraph mode Figure.text(): Support paragraph mode Oct 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature wanted good first issue Good for newcomers help wanted Helping hands are appreciated
Projects
Development

No branches or pull requests

5 participants