-
Notifications
You must be signed in to change notification settings - Fork 29
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
Discusion about API structure (and comparisons with pygmt) #689
Comments
First let me thank you for this deep thinking about the GMT.jl structure but I confess that I'm failing to to follow your points. First two are easy to reply, last two, less.
What is it that needs to stabilize/complete in the monolithic mode? All modules end up calling the monolithic mode under the hood. And
Just use Vd=2. Again,
Sorry, don't follow you here. Maybe some example?
Funny, there is an issue somewhere in |
You're right, it's not very clear without examples, I probably need to organize the ideas a bit more but maybe this will help:
Stabilize was not the right word (and on second thought it's not really about monolithic mode either), but we could think about things like thread-safety (#564), how to detect some more errors before calling gmt and some easier ways to pas in-memory data from julia to the GMT command without writing files. I confess I haven't used the GMTgrid types enough, maybe that is what I was looking for, but I ended up just running gmt as a Julia Cmd for some things since it was simple to just using GeoJSON
using DelimitedFiles
# Not a real file, just for illustration
boundaries = open("/file/with/GeoJSON_plate_boundaries.json") do file
geo2dict(GeoJSON.read(file))
end
for data in boundaries["features"]
open(`gmt plot -Wthinner,white`, write = true) do io
writedlm(io, collect(transpose(reduce(hcat, data["geometry"]["coordinates"]))))
end
end You're right, such a
That is very useful, but here I was talking about assigning some sort of import pygmt
fig = pygmt.Figure()
fig.basemap(region=[-90, -70, 0, 20], projection="M15c", frame=True)
fig.coast(shorelines=True)
fig.show() This could tie into the thread-safety thing, since we could assign one instance of the gmt API to each figure, for example. About call signatures, I was mainly just thinking to try and keep the keyword argument names/types similar to pygmt, I'll need to check for specific examples. The last point was nonsense, I initially found the pygmt code easier to follow but after looking again I think it was just because I'm more familiar with Python. As you mentioned, there is a lot of extra functionality here: maybe it can be shifted to a submodule? But again, it's just subjective. |
Maybe I can try to list some more concrete points:
|
Have you tried?
|
Why would that be nicer then?
GMT.jl follows the Julia standards of Plots.jl and others where we use the |
GMT.jl exists for quite sometime before PyGMT (for some modules it predates it for several years). For most of cases the the keyword names are equal but for others they decided to call it differently. Sometimes out of need, e.g |
It's quite likely that that you can use GMT.jl directly because either GMT and GDAL (most of it is accessible via GMT.jl) can access data subdatasets. Please provide an example of your need. Maybe in a different issue (this touches many points) or post the question in the forum. |
As a rule I try to catch the errors before sending the command to GMT, but ofc the situation is far from perfect. I guess that we have to advance in this based on a case by case basis. If you have examples of errors that should/could be catch in the Julia side, please open issues with them.
Very, very rarely GMT.jl resorts to the trick of writing temporary files and I hate when I have to do that. The memory management of grids and images is quite complicated. Julia is column-major whilst GMT, being a C lib, has arrays in row-major. This means that one must do transposes for communicating between the two. Add to it the terrible pad that basically obliges to make a copy of the array. However, GMT.jl tries a lot to avoid it by communicating with GMT via external memory objects and when grids were read via GDAL it uses the C memory layout to avoid that copy when possible. Dealing with this is awfully complicated and the situation is still far from what it ideally can become (for example always using GDAL to do projections and pass the projected array to GMT, thus avoiding any copy at all). From what I (think I) know, pygmt always duplicates the input grids or images. |
Thanks for the discussion, and just to be clear I don't mean to overwhelm you with idle requests: I'm excited about this package and I was wanting to get a sense for the kind of things that I could help with (or if such help is needed).
This fails with a MethodError from GMTdataset, because GMT does not support the GeoJSON file format. That's why I was using the GeoJSON module to load the data in this example, which works fine, but then to pass that data to GMT.jl was the part where I got stuck. I'll look into GDAL more, it seems they have a lot of readers. In other cases, I have data tables coming out of direct processing in Julia, so that's where the idea for reading from in-memory structures came from. But I will first try When I said "writting files" it's because that was what I have been doing instead of learnig to use
It's not quite the same: in pygmt the figure instance can be passed around inside the code and dataset plots can be added to it at a later stage. In a similar way, the Plots.jl functions return some kind of handle that can be captured (by default, b = basemap(region=[-90, -70, 0, 20], projection="Mercator")
c = coast!(b, shorelines=true)
# I wonder if it looks correct?
showfig(c)
# Actually, I want two maps
plt = subplot(b, c, grid=(1, 2))
# OK now we can save it
showfig(plt) # Figure is saved in current directory, could be improved by having a savefig() or similar Yes, this would require some more thought about how to integrate with
Ah, I didn't know. It's unfortunate that they have used some different conventions, but it's not a big issue. I'll leave this out of discussion unless someone suggests changes for specific cases. |
No bother, you are having only one request: the It is not well known but GMT can read the so called Now the That said, it does not seem impossible to implement your mockup case and I also would like to use subplots like in your example. But |
About reading data: I found that I can kind of read GeoJSON with (update: I've got some things working using About
Interesting, I'll need to think more about it. I had another crazy idea: what about not running the GMT session at all until |
Are you using an old GMT.jl version? Because About The problem with executing all at once in the end is that we would be forced to keep alive all instances of the data that each of the partial commands expect. But if main goal is subplot, there is a |
Hmm, actually my For now I managed to do it with I'll test out the modern mode some more then as well. |
Please post the full error trace. Still wanted to understand why the format is not detected automatically for you. |
I think I'll close this since there was still a lot of confusion from my side, and most of the things I thought about were either solved by the PR that fixed gmtread, or by better understanding of GMT/GDAL, or they require dedicated issues with better examples. I think you're right about the Figure idea: there's not a nice and easy way to do it for now. I'm currently trying out the modern mode for some new maps, I'll see how it goes :) |
If you are playing for fun with the modern mode (and no mode), consider keeping some of your experiments to expand the gallery section. It really needs a better organization and much more examples. |
This is a sort of meta-issue where I will try to summarize my thoughts about this package. I will add links to relevant trackers at the bottom as they appear.
As the first priority, I think this package can benefit from following pygmt more closely. Of course, Julia is not Python and subsequently there will be implementation details that need to change. However, using a similar structure to pygmt could be beneficial for a few reasons, at least it would be
I think the second point is important since it's a fairly niche package and finding contributors/developers with enough knowledge of
gmt
is not easy. In some areas, this package already offers more aliases and expressive syntax compared to pygmt (at least from my quick skim of the pygmt docs). I'm not suggesting to remove it, but I think adding new aliases is not a priority for now (even though I opened a few requests before 😄 ). Instead, we could focus on:"monolithic" modelow-level interface (earlier errors? more ways to pass in data?),Figure
etc. and making functions return (containers of) gmt commands instead of running them, to allow for easier incremental plottingreorganising the source code to follow pygmt structure more closely in generalI'll start to play around with the implementations when I find the time, and I also need to dig into pygmt more because I've never used it before. Let me know if it sounds like a reasonable idea.
Cheers
The text was updated successfully, but these errors were encountered: