# How to extend page size and get a perfect curved edge?

**URL:** <https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347>\
**Category:** Help\
**Created:** [November 4, 2022, 11:59pm UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347 "2022-11-04T23:59:17Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![skid.T](https://avatars.discourse-cdn.com/v4/letter/s/f9ae1b/32.png) [@skid.T](https://forum.graphviz.org/u/skid.T)\
**Post date:** [November 4, 2022, 11:59pm UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/1 "2022-11-04T23:59:17Z")

</div>

Hello graphvizers,  
I’m currently drawing a graph with Graphviz. However, the dot engine seems too stingy on page size, which leads to a weird shape of an edge:  
 ![logical](https://global.discourse-cdn.com/graphviz/original/1X/8a5789358a4a6aae08bf1c93d5f3064321cfe96d.png)

You might observe the dashed edge at the bottom looks strange. Is there any way I could make it curved and extend the page size of the graph?

```auto
digraph proofs {
	rankdir=LR
	page="7"
	splines=true
	node [shape=none label="" width=.2 height=.2]
	node [imagescale=true]
	edge [shape=none label=""]
	edge [imagescale=true]

	allx [image="images/forallx_large.png"]
	onex [image="images/existsx_large.png"]
	fofa [image="images/fofa_large.png"]

	allx->fofa [label = <<TABLE BORDER="0" ><TR><TD><IMG SCALE="TRUE" SRC="images/universalelimination_small.png"/></TD></TR></TABLE>> minlen=2]
	fofa->allx [label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/universalintroduction_small.png"/></TD></TR></TABLE>> minlen=2]
	fofa->onex [label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/existentialintroduction_small.png"/></TD></TR></TABLE>> minlen=2]
	onex->allx [style="dashed" label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/existentialelimination_small.png"/></TD></TR></TABLE> > minlen=3]

  subgraph legends { 
    label = "Legend";
    key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
      <tr><td align="right" port="i1">know rule</td></tr>
      <tr><td align="right" port="i2">possible rule</td></tr>
      </table>>]
    key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
      <tr><td port="i1">&nbsp;</td></tr>
      <tr><td port="i2">&nbsp;</td></tr>
      </table>>]
    key:i1:e -> key2:i1:w [style=dashed]
    key:i2:e -> key2:i2:w 
  }
}

```

---

<div class="post-metadata">

**Author:** ![smattr](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/smattr/32/85_2.png) [@smattr](https://forum.graphviz.org/u/smattr)\
**Post date:** [November 5, 2022, 4:39am UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/2 "2022-11-05T04:39:06Z")

</div>

I don’t have an answer to your arrow question, but you’re drawing logical transformation rules, right? Doesn’t ∃ elimination transform ∃x.F(x) into F(a)?

```auto
∃x. F(x)
  ∃E providing x = 6 ⇒
F(6)

```

---

<div class="post-metadata">

**Author:** ![skid.T](https://avatars.discourse-cdn.com/v4/letter/s/f9ae1b/32.png) [@skid.T](https://forum.graphviz.org/u/skid.T)\
**Post date:** [November 5, 2022, 5:42am UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/3 "2022-11-05T05:42:22Z")

</div>

I want to visually show my confusion to my logical philosophy instructor: he taught us the universal qualifier introduction rule, which we could introduce ∀xF(x) from F(a). Also the existential elimination rule, where ∃xF(x) and F(c)-\>B could result in B. So if we combine the universal qualifier introduction rule and the existential elimination rule, we could get ∀xF(x) from ∃xF(x). That’s really weird if we define predicate F as failing the philosophy course, any of us failing the course will lead to all of us failing the course ¯\_(ツ)\_/¯

---

<div class="post-metadata">

**Author:** ![smattr](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/smattr/32/85_2.png) [@smattr](https://forum.graphviz.org/u/smattr)\
**Post date:** [November 5, 2022, 3:30pm UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/4 "2022-11-05T15:30:01Z")

</div>

Ah I see. Yes, anyone failing philosophy leading to everyone failing philosophy does indeed seem surprising 🙂

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [November 5, 2022, 4:46pm UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/5 "2022-11-05T16:46:33Z")

</div>

(no thoughtful philosophy or logic comments, that was too long ago)  
There are a couple of modest flaws in your graph, though they are not “the problem”

- instead or **page** (postscript-only) you wanted **size** (with a trailing “!”)
- the **label** attribute only applies to Root graphs and clusters

In my opinion, the best way to attach your legend to the graph is to create two distinct graphs and usr **gvpack** ([http://www.graphviz.org/pdf/gvpack.1.pdf](http://www.graphviz.org/pdf/gvpack.1.pdf)) to glue them together.  
However, below is a reworked version of your graph including the legend. Because I did not have your images, may need to tweak things a bit :

```auto
digraph proofs {
	//rankdir=LR // use std. ranking
	// size="7!" // page is only for postscript
	splines=true
	node [shape=none label="" width=.2 height=.2]
	node [imagescale=true]
	edge [shape=none label=""]
	edge [imagescale=true]
	nodesep=.6 // spread things out
	ranksep=.8 // spread things out

  {rank=same
	allx [image="images/forallx_large.png"]
	onex [image="images/existsx_large.png"]
	fofa [image="images/fofa_large.png"]
  }
	allx->fofa [label = <<TABLE BORDER="0" ><TR><TD><IMG SCALE="TRUE" SRC="images/universalelimination_small.png"/></TD></TR></TABLE>> minlen=2]
	fofa->allx [label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/universalintroduction_small.png"/></TD></TR></TABLE>> minlen=2]
	fofa->onex [label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/existentialintroduction_small.png"/></TD></TR></TABLE>> minlen=2]
	onex->allx [style="dashed" label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/existentialelimination_small.png"/></TD></TR></TABLE> > minlen=3]

  subgraph clusterlegends { 
    label = "Legend";
    {rank=same
    key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
      <tr><td align="right" port="i1">know rule</td></tr>
      <tr><td align="right" port="i2">possible rule</td></tr>
      </table>>]
    key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
      <tr><td port="i1">&nbsp;</td></tr>
      <tr><td port="i2">&nbsp;</td></tr>
      </table>>]
    key:i1:e -> key2:i1:w [style=dashed]
    key:i2:e -> key2:i2:w
    }
  }
  key:i2:sw -> allx [style=invis] // place legend above graph
}

```

Giving:  
 ![rule1](https://global.discourse-cdn.com/graphviz/original/1X/49832453588cbfc04bc2e60c86556435575cc2df.png)

---

<div class="post-metadata">

**Author:** ![skid.T](https://avatars.discourse-cdn.com/v4/letter/s/f9ae1b/32.png) [@skid.T](https://forum.graphviz.org/u/skid.T)\
**Post date:** [November 6, 2022, 6:32am UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/6 "2022-11-06T06:32:22Z")

</div>

> [@steveroush](#):
>
> ```auto
> digraph proofs {
> //rankdir=LR // use std. ranking
> // size="7!" // page is only for postscript
> splines=true
> node [shape=none label="" width=.2 height=.2]
> node [imagescale=true]
> edge [shape=none label=""]
> edge [imagescale=true]
> nodesep=.6 // spread things out
> ranksep=.8 // spread things out
> 
> {rank=same
> allx [image="images/forallx_large.png"]
> onex [image="images/existsx_large.png"]
> fofa [image="images/fofa_large.png"]
> }
> allx->fofa [label = <<TABLE BORDER="0" ><TR><TD><IMG SCALE="TRUE" SRC="images/universalelimination_small.png"/></TD></TR></TABLE>> minlen=2]
> fofa->allx [label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/universalintroduction_small.png"/></TD></TR></TABLE>> minlen=2]
> fofa->onex [label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/existentialintroduction_small.png"/></TD></TR></TABLE>> minlen=2]
> onex->allx [style="dashed" label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/existentialelimination_small.png"/></TD></TR></TABLE> > minlen=3]
> 
> subgraph clusterlegends { 
> label = "Legend";
> {rank=same
> key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
> <tr><td align="right" port="i1">know rule</td></tr>
> <tr><td align="right" port="i2">possible rule</td></tr>
> </table>>]
> key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
> <tr><td port="i1">&nbsp;</td></tr>
> <tr><td port="i2">&nbsp;</td></tr>
> </table>>]
> key:i1:e -> key2:i1:w [style=dashed]
> key:i2:e -> key2:i2:w
> }
> }
> key:i2:sw -> allx [style=invis] // place legend above graph
> }
> 
> ```

Hi steveroush. Thanks your help. This looks amazing:

 ![logical](https://global.discourse-cdn.com/graphviz/original/1X/fde775f8536a5d6fd4a5f5b3f3a222a3530b7aa6.png)  
However, is it possible to make the image label above or below the line for the long dashed edge rather than crossing it? Here are the dot file after adjustment and the images:

```dot
digraph proofs {
	node [shape=none label=""]
	node [imagescale=true]
	edge [shape=none label=""]
	edge [imagescale=true]
	nodesep=.6 // spread things out
	ranksep=.8 // spread things out

  {rank=same
	allx [image="images/forallx_large.png"]
	onex [image="images/existsx_large.png"]
	fofa [image="images/fofa_large.png"]
  }
	allx->fofa [label = <<TABLE BORDER="0" ><TR><TD><IMG SCALE="TRUE" SRC="images/universalelimination_small.png"/></TD></TR></TABLE>> minlen=2]
	fofa->allx [label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/universalintroduction_small.png"/></TD></TR></TABLE>> minlen=2]
	fofa->onex [label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/existentialintroduction_small.png"/></TD></TR></TABLE>> minlen=2]
	onex->allx [style="dashed" label = <<TABLE BORDER="0"><TR><TD><IMG SCALE="TRUE" SRC="images/existentialelimination_small.png"/></TD></TR></TABLE> > minlen=3]

  subgraph clusterlegends { 
    label = "Legend";
    {rank=same
    key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
      <tr><td align="right" port="i1">possible rule</td></tr>
      <tr><td align="right" port="i2">known rule</td></tr>
      </table>>]
    key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
      <tr><td port="i1">&nbsp;</td></tr>
      <tr><td port="i2">&nbsp;</td></tr>
      </table>>]
    key:i1:e -> key2:i1:w [style=dashed]
    key:i2:e -> key2:i2:w
    }
  }
  key:i2:sw -> allx [style=invis] // place legend above graph
}

```

[universalintroduction\_small.png](https://forum.graphviz.org/uploads/short-url/jpNP1W6I96z1unv4E4xXhIUGEZ0.png)  
[universalelimination\_small.png](https://forum.graphviz.org/uploads/short-url/FQX5lubFKTm7Hyw7FszcGmWoCV.png)  
[existentialintroduction\_small.png](https://forum.graphviz.org/uploads/short-url/uruTrkMMBtzS1JuMn7Pb4VY9nRG.png)  
[existentialelimination\_small.png](https://forum.graphviz.org/uploads/short-url/rSrZ2O2mQDK8tbBmBzOTaAWCY5c.png)  
[forallx\_large.png](https://forum.graphviz.org/uploads/short-url/jB2ZIczs2W3ZeacUg3XGNqjTAih.png)  
[fofa\_large.png](https://forum.graphviz.org/uploads/short-url/zeYFFomV95ZWfYM0RV0xoykBVDC.png)  
[existsx\_large.png](https://forum.graphviz.org/uploads/short-url/3Nw75vYGfHl3sOTrpEOQt2RevUi.png)

---

<div class="post-metadata">

**Author:** ![mark](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/mark/32/84_2.png) [@mark](https://forum.graphviz.org/u/mark)\
**Post date:** [November 6, 2022, 11:17am UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/7 "2022-11-06T11:17:54Z")

</div>

Just my 2c: for such a small graph, and wanting exact layout, you might be better off with an SVG editor rather than Graphviz.

Graphviz shines when you don’t know how to layout your graph (perhaps because it’s big), and Graphviz can do the layout for you. SVG editors are better at specifying exact layout and edge shapes.

---

<div class="post-metadata">

**Author:** ![scnorth](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/scnorth/32/89_2.png) [@scnorth](https://forum.graphviz.org/u/scnorth)\
**Post date:** [November 6, 2022, 12:06pm UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/8 "2022-11-06T12:06:07Z")

</div>

This is good advice. The Graphviz path router has several main heuristics. An overview was published long ago: [https://dl.acm.org/doi/10.1145/276884.276935](https://dl.acm.org/doi/10.1145/276884.276935)

The edge router has a heuristic that looks for places where a straight axis-aligned segment can be made. This is meant to reduce the spaghetti effect that people still complain about.

This is an area of Graphviz where someone with some new ideas could pitch in. It might not be hard to disable this particular heuristic for individual edges or globally. Also, it might be nice to make multiple flat edges between the same endpoint more symmetric.

One thing that works against this is the abundance of features, like edge port constraints, labels, and the presence of other edges including self-edges (or loops).

There’s a more general question of what makes curved edges in diagrams look nice. It’s interesting that Gephi and probably some successors chose to have curved edges even if there are no constraints to prevent unwanted overlaps. We made this an option in Graphviz too (splines=curved as shown in [splines | Graphviz](https://graphviz.org/docs/attrs/splines/)) but it was probably coded in a half hour after a discussion over lunch in the cafeteria and might benefit from more work.

As mentioned elsewhere, Keenan Crane did some great work on a novel method of using repulsive forces between curves for various applications including graph drawing, and uses Graphviz as a bogey [Keenan Crane - Repulsive Curves](https://www.cs.cmu.edu/~kmcrane/Projects/RepulsiveCurves/index.html) Also a nice intern-level project would be to implement this code in Graphviz.

We wonder if anyone has been able to characterize what people consider to be the most aesthetically pleasing and/or most readable curves drawn around obstacles in diagrams. Relevant properties include smoothness, shortness, symmetry, number of inflections, angular and euclidean separation. Placement of edge labels must also be considered.

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [November 6, 2022, 9:02pm UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/9 "2022-11-06T21:02:26Z")

</div>

To get the image off of the dotted line, change **label** to **xlabel**  
Giving:

 ![logic1](https://global.discourse-cdn.com/graphviz/original/1X/8d324a4f0bc037b93c6f249696cf17c0861c4cee.png)

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [November 6, 2022, 9:15pm UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/10 "2022-11-06T21:15:59Z")

</div>

My 1c: I like the **pikchr** ([Pikchr: Documentation](https://pikchr.org/home/doc/trunk/homepage.md)) implementation of the PIC language. Though not gui, like Graphviz it is text based and scriptable. While it has no routing capabilities, it has more features than Graphviz in describing text placement, (relative) node placement, and simple edge placement.  
I’d like to see some of these capabilities added to Graphviz - maybe in my next lifetime.

---

<div class="post-metadata">

**Author:** ![smattr](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/smattr/32/85_2.png) [@smattr](https://forum.graphviz.org/u/smattr)\
**Post date:** [November 7, 2022, 3:25am UTC](https://forum.graphviz.org/t/how-to-extend-page-size-and-get-a-perfect-curved-edge/1347/11 "2022-11-07T03:25:19Z")

</div>

Graphviz can render to PIC, so it’s probably doable to write a translator in the other direction.
