Skip to content

Discussion: Improve -B for GMT 6 via long-format options #254

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

Open
PaulWessel opened this issue Dec 30, 2018 · 5 comments
Open

Discussion: Improve -B for GMT 6 via long-format options #254

PaulWessel opened this issue Dec 30, 2018 · 5 comments
Labels
discussion Topics for longer discussion

Comments

@PaulWessel
Copy link
Member

The complicated -B option has been with us since GMT 1. In GMT 5 we broke it up into several -B options that set different aspects of basemap specifications. However, it remains a very busy and unclear option. Let us see what needs to be set when a basemap is required in GMT:

1. The Canvas/Frame

  • Which axes to plot and how (via combination of codes WESNwesnlrbtZzu) [Default is MAP_FRAME_AXES]
  • Optionally paint canvas with uniform color (via +gfill) [No fill]
  • Optionally add plot title (via +t"my title") [no title]
  • Optionally suppress all frames and annotations (via +n)
  • For geographically oblique gridlines from another pole (via +olon/lat) [North pole; Rare usage]
  • For 3-D plots, we may wish to outline the 3-D box and see x-z, y-z gridlines, if selected (via +b) [no box]

2. Axes

Each of the axes we selected have many sub-settings. Furthermore, there are potentially two separate annotation/tick/gridline systems per axis: p - primary (Default, closest to axis) and s - secondary (farther from axis). Each system has many settings:

  • annotation interval (a)
  • tick interval (f)
  • gridline interval (g)
  • annotation prefix prepended to annotations (+p)
  • annotation unit appended to annotations (+u)
  • Axis label (+l|L)
  • Secondary axis label (+s|S) if different

3. Intervals

  • Intervals (e.g., annotation, tick, gridline) have settings too. By default they are placed at integer multiples of the given interval, but this placement can be phase-shifted by adding +|-phase [0].
  • Intervals take units and these may scale the interval but may also imply how numbers might be formatted (mostly applies to time axes).
  • Some intervals can be given as multiples or fractions of pi which means the pi symbol (and factors/fractions) are used in the annotations.
  • For log10 axis the intervals can be 1,2,3 or even negative; codes p and l imply different formatting.
  • For power axis code p implies different formatting.
  • For custom annotations a c is given instead of a,f,g (the file will have these settings).

Draft proposal for discussion:

Introduce additional long-format --option=* options to clarify how to give basemap specifics. They do not replace -B but can be used instead of -B. Like the other long-format options (#230) they will be available to both classic and modern mode.

  1. Canvas/frame:
  • --frame=|none[+fill=fill][+pole=lon/lat]
  • Break out separate --title=title
  1. Axis: (below, int can be none, auto, a numerical value with optional appended unit character, or name of file with custom annotations, tickmarks, and gridspacings)
    The first set apply to the primary (or only) axes system:
  • --annotations=int[+phase=phase][+prefix=txt][+unit=unit]
  • --ticks=int[+unit=unit][+phase=phase]
  • --gridlines=int[+unit=unit][+phase=phase] Default is none

The second set apply to the secondary axes system:

  • --secondary-annotations=int[+phase=phase][+prefix=txt][+unit=unit]
  • --secondary-ticks=int[+unit=unit][+phase=phase]
  • --secondary-gridlines=int[+unit=unit][+phase=phase] Default is none

There is only one label per axis but the E, N, U axes could have an "other" label:

  • --xlabel=xlabel
  • --ylabel=ylabel
  • --zlabel=zlabel
  • --other-xlabel=xlabel
  • --other-ylabel=ylabel
  • --other-zlabel=zlabel

The labels are given their own long option per axis to avoid difficulties in parsing free-form text separated by slashes (which could be part of the text); this is also why --title is a separate option.

The defaults are the same as before but needs a trigger --frame=default (like -Baf is needed today):

--frame=<MAP_FRAME_AXES>
--annotations=auto
--ticks=auto
--gridlines=none

There is some duplications here: --frame=none is the same as --annotations=none --ticks=none
A few simple examples:

	-Baf 
	-BWSne+gred -Baf
	-Bx30f10g5 -By2f1
	-B+glightgray+t"My plot" -Bxaf+l"X-axis" -Byaf+l"Y-axis"

would become

	--frame=default
	--frame=WSen+fill=red
	--annotations=30/2 --ticks=10/1 --gridlines=5/none
	--frame=default+fill=lightgray --xlabel="X-axis" --ylabel="Y-axis" --title="My plot"

Pre-parsing of these long-format options in gmt_init_module will result in a series of corresponding short -B options that the standard GMT parser can handle.

Note that external interfaces may break these down further (e.g., 'x-annotations', [1 3 15 19]) but can then concatenate these separate axis settings to the required --annotations=argument format.

Please give feedback on the chosen long-options and suggest improvements. The goal is to converge on the right set of long-format options and house the parsing of these in the C API and thus relieve the external interfaces from doing tedious parsing when preparing calls to GMT via GMT_Call_Module.

@joa-quim
Copy link
Member

I surely like this and I think it will really help the command line users. But I don't see how it can be of use for external interfaces. The fact that longoptions start with -- is a killing feature. One cannot name variables starting with a minus (Julia, Matlab, Python, R, etc), so external wrappers will still need to entirely implement their own parsing.

Sure that, at least in Julia, even without any further changes, it will be possible to say frame="--annotations=30/2 --ticks=10/1 --gridlines=5/none" but again, those -- look awful.

On the other hand frame (or axis, like in matplotlib and other Julia plotting libs) is what I called in Julia to the entire -B option, and here it is used in a much more reduced context, so mixing the two would be very confusing.

--secondary-annotations and alike for the secondary axis is so loooong. An alternative is to introduce a frame2 (or a axes2 like I do in Julia) and then just keep using annotations, ticks, etc to mean specifications of the secondary axis.

@PaulWessel
Copy link
Member Author

Thanks. However, I did not imagine the external interfaces using --. My thought was that they would supply keyword/arguments, e.g., 'frame=WSne+fill=red' or (..., frame, 'WSne+fill=red', ...) and then your parser would add the leading -- when passing the command string to GMT. You would not have to reassemble all these pieces into a valid -B option as they would be done in the C API.

As for the very long --secondary-annotations, etc. Well, to be discussed. One purpose of having long arguments is to make it very clear what they are. This one does, of course, but axis2 requires more documentation. Anyway, perhaps we can have aliases like annotations2 that is the same as secondary-annotations (and --primary-annotations is the same as annotations), for instance.

@joa-quim
Copy link
Member

Well, the point for me is that I already wrote a parser that does all that (and more, like allow specifying the axis separately, does not use any + sub-options because they can the their own keyword (this allows expanding pen, etc)).

I was think in proposing to use strncp() in the parser so both annot and annotations would do (same for grid vs gridlines) and that won't work with the annotations2 idea.

@PaulWessel
Copy link
Member Author

Sure, part of the complication is that the GMT team did not have this discussion before the external interface work started. I still think it is a good goal to standardize on a set of keywords and to put as much of any long-format parsing into GMT API as possible. However, I am not sure if it makes sense to decouple modifier arguments into separate options since there will be collisions between two or more pens or colors on the same command line. It would surely complicate the parser to know what module is needing what.

@joa-quim
Copy link
Member

Yes, sure that have a standardized name for the keywords is a good thing, but it's more complicated to standardize the rest. For example, in Julia I can (do) have

decorated(n_symbols=5, symbol=:star, symbsize=1, pen=(0.5,:green), fill=:blue, quoted=1)

which is only the argument to-S~. As you see the +p is here expanded in pen=(0.5,:green) and there is no risk to clash with other pens of other args because it's isolated in its context. We cannot do the same in command line.

@joa-quim joa-quim added the discussion Topics for longer discussion label Jan 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Topics for longer discussion
Projects
None yet
Development

No branches or pull requests

2 participants