Feature #765

Add option to psxy to make lines and/or arrows stop before end

Added by Remko about 6 years ago. Updated almost 6 years ago.

Status:ClosedStart date:2015-09-17
Priority:NormalDue date:
Assignee:Paul% Done:


Category:-Estimated time:12.00 hours
Target version:Candidate for next minor release


This option should make it possible to link two circle symbols with a line, while the line does not cross into the symbol.
For example, when the radius of the symbol is 10pt, then the user should be able to define a distance of, say, 12 pt to the end (and begin) where no line will be draw.
Arrows then also should be drawn only to the new end points.

Something similar is possible in the LaTeX package PSTricks.
Maybe we can learn something from it.

See the attachment as example.

screenshot4.jpg - Example of what arrows stopping short of the end. (65.3 KB) Remko, 2015-09-17 04:09


#1 Updated by Paul about 6 years ago

  • Status changed from New to Feedback

For simple lines the workaround is to plot the lines first, then plot circles on top. Only case when this fails is you insist on a non-filled circle, of course.
For vectors there is no simple way to do this at the moment. I wonder if it is as simple as to shorten each end by <delta>[c|i|p]. So for vectors it may mean adding a +o<off> modifier to offset start and stop point of a vector by this amount (maybe +o[b|e]<off> to be able to select just one of the ends). Since we are talking about line segments between points such lines are basically headless vectors and can be drawn the same way.

#2 Updated by Remko about 6 years ago

Yes, of course, there is a work around to plot symbols on top of the lines, but as you said that does not work with open symbols, and also not when you want to stop the line short of the symbol by some distance. For arrows (vectors) it does not work at all.

Indeed I had the idea that it would be able to define some offset (possibly for either end of the line segment), as you suggested. And yes, it should be consistent between vectors and lines. So if you set the offset in some fashion, and then define that there should be vectors (-Sv) then the vector heads automatically stop short as well.

#3 Updated by Paul about 6 years ago

I think this is a simple thing to implement if we are limiting ourselves to line segments, i.e., single lines from point A to B. IF these are plotted via -Sv+s then I could probably add this in a hurry. If you want this to work on lines (i.e., many points that constitute a line) then it is more complicated, but perhaps not. Is there any need for this to work on general lines or could it be limited to two-point segments?

#4 Updated by Remko about 6 years ago

Let's think about this. Initially I would like to be able to draw a line from A to B leaving a gap around A and B.
This line ought also to be able to become an arrow.
This is already entirely different from the current implementation of psxy, where the vector is basically treated as a symbol at A, stretching to point B. I don't know if this includes great circle lines.
My preferred behaviour would be that there was something like an option that simply makes all segments (which can run along a number of nodes) begin and/or end in an arrow.
I add here "along a number of nodes", because we would like to support Bézier curves as well.
Hence something like:

psxy -W1p ... <<END
x0 y0
x1 y1
will draw a line from A(x0,y0) to B(x1,y1). Keeping the same input modification of this would be:
psxy -W1p+o<offset>
to clip the line <offset> before reaching A and B. E.g. 12p.
Then if we want vector heads on that, we could use something like:
psxy -W1p+o<offset>+v<size>+<vector_options>
where <vector_options> are a bunch of the ones from -Sv

Ultimately, we should be able to do this for curved lines as well. Something like:

psxy -W1p+c <<END
x0 y0
x2 y2
x1 y1
to make a curved line starting at A, and ending at B, with a guide point C(x2,y2) somewhere in between.
On top then come the vector options:
psxy -W1p+c+v<size>+<vector_options>

#5 Updated by Paul about 6 years ago

I see. Given all our map clipping and 360-wrapping machinery this will be a major feature to implement. It is also independent from doing something similar to the vector symbol itself (-Sv). I don't know the demand for any of these features but since the enhancement to vectors should be relatively straightforward I suggest we start with that and gain some experience with the usefulness of shortening such line segments. I understand this does not address your wider issue but that one I think requires much more motivation to attempt implementing at the moment. I will look at the vector part. I suspect the only challenging portion will be for geovector where the offset +o will be in km or degrees etc.

#6 Updated by Paul about 6 years ago

Doing this for vectors have now been implemented (r14882). However, lines will be more interesting. Just wanted to add one more comment on lines. Fluid dynamicists like to plot flowline plots which are like a contour map where the contours have direction indicated by arrows. So I can imagine it may be desirable to have a generic routine to draw lines with arrows, and arrow placement would inherit the machinery for label placement, basically.

#7 Updated by Paul about 6 years ago

The more I think of this, the more it resembles the ability to place a label somewhere along a line (i.e., contour labels and quoted lines). For instance, placing a circle every 200 km along a line is a useful option that presently would require some scripting with mapproject, and placing arrows in an orderly fashion is very nontrivial (via script involving x2sys to find intersections between the lines and helper lines). One possible path forward is this:

  1. For grdcontour and pscontour: Add modifier +z<size><vectorparameters> to the -A option, which would replace labels by vector heads, giving the vector parameters.
  2. For psxy and psxyz: Add "symbol" -Sz which takes the same methods as -Sq (i.e., d|f|n|l|x), but also requires another symbol -S* to be specified as the actual symbol, with -Sz simply describing where those symbols will be plotted along the given lines.

This scheme would have the great benefit of being simple to implement (we basically duplicate the "find label location" code but then just plot the required symbol instead of a text), with all the pieces already existing. You will see I limit the contour programs to just do an arrow to avoid having to introduce all the symbols possible in psxy. Thus, people wanting to place squares along contours would have to dump contours via -D and then feed via psxy instead.

Regarding direction of vector heads: For psxy and lines there clearly is a well defined notion of "forward". For contours we would have to indicate what that is: usually we say forward is such that the left side of the contour is uphill.

Addressing the initial question of leaving a gap at the start and stop of the line could be dealt with via a new modifier to the quoted line machinery, e.g., +q<skip>, where skip is one (or two) distances that indicate we should start and stop the actual drawing by those amounts from the original end points. We already have code that computes the distances along the lines (in support of the d method) so nothing new to add here either - in this case the skip might even be real-world distances instead of plot distance.

#8 Updated by Paul almost 6 years ago

Remko, perhaps your idea of -W<pen>[+b][+o<offsets>] is better than messing with -Ab. [+b] would be "resample line with Bezier spline". I also agree with your end vector option. OK to implement?

#9 Updated by Paul almost 6 years ago

  • Status changed from Feedback to Resolved
  • Assignee changed from Remko to Paul
  • % Done changed from 0 to 100

This has now been implemented in r14975 via -W<pen>[+o<offsets>]. Only used in psxy for starters.

#10 Updated by Paul almost 6 years ago

  • Status changed from Resolved to Closed

Closing this issue as implemented and working in psxy.

Also available in: Atom PDF