I create a visualization of all nodes and edges involved in the shortest path between two vertices. Without providing unnecessary details, nodes represent organisms, and edges represent relationships between parents and children. The axis of the node axis indicates its birth, while the y axis is simply the index of the node in the path (adjacent nodes are separated by a unit value).
I will show my problem with the following training dataset:
xstart=c(1966, 1967,1977,1975,1958) ystart=c(1.1,2.1,3.1,4.1,5.1) xend=c(1967,1977,1975,1958,1958) yend=c(1.9,2.9,3.9,4.9,5.1) x=c(1966,1967,1977,1975,1958) y=c(1,2,3,4,5) xustart=c(1964,1965,1975,1973,1956) xuend=c(1968,1969,1979,1977,1960) yustart=c(0.9,1.9,2.9,3.9,4.9) yuend=c(0.9,1.9,2.9,3.9,4.9) xostart=c(1964,1965,1975,1973,1956) xoend=c(1968,1969,1979,1977,1960) yostart=c(1.1,2.1,3.1,4.1,5.1) yoend=c(1.1,2.1,3.1,4.1,5.1) label=c("node1","node2","node3","node4","node5") path.plot <- data.frame(label,xstart,ystart,xend,yend,x,y)
If I just create nodes and edges (where the edges enter and leave nodes in the center of the x-value of the text label), I find the visual appearance unattractive:
ggplot(data=path.plot) + geom_segment(aes(x=xstart, y=ystart, xend=xend, yend=yend)) + geom_text(aes(x=x, y=y, label=label))
I think this looks a little better with underscores, but still messy:
ggplot(data=path.plot) + geom_segment(aes(x=xstart, y=ystart, xend=xend, yend=yend)) + geom_segment(aes(x=xustart, y=yustart, xend = xuend, yend = yuend)) + geom_text(aes(x=x, y=y, label=label))
Honestly, I thought that when the edges connect to the bottom left corner, and writing the corners of the underline text label will look better (for example, the inbound edge connects to the left underscore, the outbound edge connects to the right underline).
However, this would not work as node1 and node2, where the edge exiting node1 would intersect part of the text, and also end as the edge of the negative slope, which could be tricked because node2 is at a later date (1967) than node1 ( 1966).
So, I tried both underline and overlay:
ggplot(data=path.plot) + geom_segment(aes(x=xstart, y=ystart, xend=xend, yend=yend)) + geom_segment(aes(x=xustart, y=yustart, xend = xuend, yend = yuend)) + geom_segment(aes(x=xostart, y=yostart, xend = xoend, yend = yoend)) + geom_text(aes(x=x, y=y, label=label))

I think this looks better, but if you have suggestions for improvement, I would take that into account. Anyway, my main question is how to create the width of the underscores / add-ons in proportion to the width of the node label? Because my node headers will not always have the same length (for example, I used only generic names). Their labels can vary greatly in length, so a constant underline does not work.
Another problem with the current / overline underline is that if I adjust the size of the image, the length of the text labels will change in proportion to the length of the underline / overline, and suddenly it looks ridiculous! Thus, I think that I am also trying to find a way to associate the length of the underline / superscript with the length of the text so that they are not only guaranteed in proportion, but also guarantee that they will remain proportional when the image size is equal corrected.
Thanks...
I took into account the strwidth parameter and the rectangles (from the first comment) - it looks visually attractive. However, I still have problems resizing (label length and rectangle length are not saved when resizing the image). For example, if I make the image a little smaller in my Studio R graphics window, the labels expire in rectangles. I do not use a static image, so I just canβt just save the image in the correct size.
The following is what I did as an update, but still wondering if I can maintain label / rectangle length proportions even when changing the overall image:
# Made one label longer than the others label=c("node1","node238968396849223","node3","node4","node5") textFrame = data.frame(x = x, y = y, label = label) textFrame = transform(textFrame, w = strwidth(label, 'inches') + 0.25, h = strheight(label, 'inches') + 0.25 ) ggplot(data = path.plot,aes(x = x, y = y)) + geom_rect(data = textFrame, aes(xmin = x - strwidth(label, "inches")*1.2, xmax = x + strwidth(label, "inches")*1.2, ymin = y-.1, ymax = y+.1), fill = "grey80") + geom_segment(aes(x=xstart, y=ystart, xend=xend, yend=yend)) + geom_text(data = textFrame,aes(x = x, y = y, label = label), size = 4)