How to control the points of splines?

Hi, all.

The documentation of “splineType” as follows.

splineType

spline ( ';' spline )*

  • where spline = (endp)? (startp)? point (triple)+
  • and triple = point point point
  • and endp = "e,%f,%f"
  • and startp = "s,%f,%f"

If a spline has points p₁ p₂ p₃ … pₙ, (n = 1 (mod 3)), the points correspond to the control points of a cubic B-spline from p₁ to pₙ. If startp is given, it touches one node of the edge, and the arrowhead goes from p₁ to startp. If startp is not given, p₁ touches a node. Similarly for pₙ and endp.

But the following codes don’t work.

#python3.6
dot = Digraph()
dot.attr(rankdir=‘LR’)
dot.graph_attr[‘layout’] = ‘fdp’
dot.graph_attr[‘splines’] = ‘curved’

dot.node(‘A’, ‘A’, shape = ‘doublecircle’, pos=‘0,0!’)
dot.node(‘B’, ‘B’, shape = ‘doublecircle’, fontsize=‘8’, height=‘1’,pos=‘2,0!’)

dot.edge(‘A’,‘B’,‘C’,pos=“spline(”(e,2,1);(s,0,1);(1.1,1.1);(1.2,1.2);(1.3,1.3)")

And the result I want just like this.

image

Thanks a lot!

(I am not a mathematician, bear with me) (splines are a major source of heartburn)
I think you are missing a point - you need four.
Ignoring the optional “start” and “end” points that define arrowheads, a spline needs four points followed by zero or more sets of three points or spline = (endp)? (startp)? POINT (triple)+. (note POINT)
Each generated spline segment needs four points. When considering triples, the last point in the previous set is used as the fourth point. (poorly worded).
Note that the spline points are NOT “draw a curve through these points”. For a non-mathematician (me) spline points are “draw a curve using these points in a magical/mathematical way that does not touch, but uses them for guidance”.
Graphviz seems to usually generate 7 (4 then 3) points for simple curves (ignoring arrowheads), but 4 points work fine.
See also: Fun with edges!

Yes, exactly. We were targeting Postscript’s piecewise cubic Bézier curves which as you say always have 4 + 3n points.

Thank you very much for your reply. I 've learn a lot from your article
Fun with edges! (bear with my poor coding I can’t get the method you guide the spline crying…)

And I still have a problem when use Graphviz in python.

Here is my code.

#Python3.6
dot1 = Digraph(“1”)
dot1.attr(rankdir=‘LR’)
dot1.graph_attr[‘layout’] = ‘neato’ #fdp,neato
dot1.graph_attr[‘splines’] = ‘true’ #compound,curved,true

dot1.node(‘a’,shape=“point”,pos=“0,0!”,color=“blue”)
dot1.node(‘b’,shape=“point”,pos=“10,0!”,color=“green”)
dot1.node(‘c’,shape=“point”,pos=“5,5!”,color=“red”)

dot1.edge(‘a’,‘b’,pos=‘10,0 0,0 1,1 2,2 3,3 5,5 7,3 8,2 9,1’) #It doesn’t work.

dot1.view()

I have tried
“dot1.edge(‘a’,‘b’,pos=‘10,0 0,0 1,1 2,2 3,3 5,5 7,3 8,2 9,1’)”
“dot1.edge(‘a’,‘b’,pos=‘e,10,0 s,0,0 1,1 2,2 3,3 5,5 7,3 8,2 9,1’)”
in python, but they don’t work neither.

Do you know the correct expression to guide the spline in python?
Thanks a lot!

Do you know the correct expression to guide the spline in python?
Thank you very much!

I do not use Python to generate Graphviz code, so just guessing:

  • What does don’t work mean? Error message, no edge, weird edge, …?
  • expect this to fail: not 4,7, or 10 points: dot1.edge(‘a’,‘b’,pos=‘10,0 0,0 1,1 2,2 3,3 5,5 7,3 8,2 9,1’)
  • expect this to be OK (7 points + e & s) dot1.edge(‘a’,‘b’,pos=‘e,10,0 s,0,0 1,1 2,2 3,3 5,5 7,3 8,2 9,1’)

Best guess, you are missing the -n2 commandline option for neato - see FAQ | Graphviz and pos | Graphviz

In python you would need a specific graphics or plotting library. matplotlib already has cubic Beziers. See for example Path Tutorial — Matplotlib 3.6.3 documentation