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

Allow Figure.legend to read from StringIO #571

Closed
dr-glenn opened this issue Aug 26, 2020 · 5 comments · Fixed by #3438
Closed

Allow Figure.legend to read from StringIO #571

dr-glenn opened this issue Aug 26, 2020 · 5 comments · Fixed by #3438
Labels
feature request New feature wanted
Milestone

Comments

@dr-glenn
Copy link

I need to display a legend of symbols for the magnitude of earthquakes. Currently the legend specification must be a file on disk. The Pythonic implementation should allow Figure.legend(spec=<buffer|file>,...). My preference is to write the legend specification to io.StringIO buffer and then use the buffer for Figure.legend. Instead I have to generate the legend spec in program and write to a file and then specify spec='my_legend.txt'.

Figure.legend has default arg spec=None. I have no idea how this default works, that's a separate issue: improve documentation.

I am willing to implement, but have no experience with such participation.

@welcome
Copy link

welcome bot commented Aug 26, 2020

👋 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.

@seisman seisman added the feature request New feature wanted label Aug 26, 2020
@seisman
Copy link
Member

seisman commented Aug 26, 2020

That's a good point. Currently PyGMT doesn't support StringIO, but I agree it should.

Figure.legend has default arg spec=None. I have no idea how this default works, that's a separate issue: improve documentation.

A quick answer to your question:

GMT6 supports a feature called "auto-legend". For Figure.plot() function, you can add the argument label="XXX", then when you call Figure.legend(), it will automatically add a legend for you.

See this example for how it works. For detailed syntax, please refer to the GMT -l option.

@weiji14
Copy link
Member

weiji14 commented Aug 26, 2020

Hi @dr-glenn, could you provide an example on how you are writing to the io.StringIO buffer? I know pandas has a to_string function that can write dataframes/tables to StringIO, but not sure if this is what you're referring to. Some lines of code to show how you're doing this would be great!

Currently PyGMT doesn't support StringIO, but I agree it should.

I'll second this. There's at least two ways this can be implemented:

  1. Write the StringIO to a temporary .txt file behind the scenes, and pass that onto GMT. Quite hacky, and might not be good for large StringIO buffers, but it should be doable.
  2. Find a way to let the GMT C API read from the StringIO buffer directly (without an intermediate temporary txt file). I'm not too familiar with how StringIO buffers actually work, but I think someone with the right skills (or willing to learn them) can do it.

@dr-glenn
Copy link
Author

dr-glenn commented Sep 9, 2020

I apologize for not answering the request for example much sooner. This example is quite trivial and you may well wonder why I care at all - it's just that I don't like writing files when not needed, plus many Python functions expect a file pointer/buffer object rather than a filename.
I note that others have already moved forward with RFC on #576.

# create a map legend for earthquake magnitude
# find magnitude limits for a legend
mag_min = int(data.mag.min())
mag_max = int(data.mag.max() + 1.0)
mags = range(mag_min, mag_max)
mag_sym_size = [0.02 * 2 ** m for m in mags]
# write symbols to internal file
#sio = io.StringIO()    #  NOTE - this is the code that doesn't work with PyGMT
sio = open('quake_mag_sym.txt','w')    # NOTE: must use actual file with PyGMT
for mag,ms in zip(mags,mag_sym_size):
    # S 0.1i c 0.15i p300/12 0.25p 0.3i This circle is hachured
    # S 0.1i e 0.15i yellow 0.25p 0.3i This ellipse is yellow
    if ms > 1.0:    # need extra space above big symbol_ex
        sio.write('G 1l\n')
    sio.write('S 0.1i c %.1f yellow 0.25p 0.3i M=%d\n' % (ms,mag))
#sio.seek(0)
sio.close()
# legend in the upper right
fig.legend(spec='quake_mag_sym.txt')    # NOTE: would prefer to use a buffer/StringIO

@weiji14
Copy link
Member

weiji14 commented Sep 19, 2024

FYI, @seisman has implemented option 2 from #571 (comment) ("let the GMT C API read from the StringIO buffer directly") at #3438 (there's an example in that PR on how to pass in an io.StringIO buffer to fig.legend. There's an open issue to document this in a gallery example at #3444.

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
3 participants