Skip to content
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

Arrowhead edges for directed graphs do not point properly #3562

Open
jaco0797 opened this issue Mar 19, 2019 · 14 comments
Open

Arrowhead edges for directed graphs do not point properly #3562

jaco0797 opened this issue Mar 19, 2019 · 14 comments

Comments

@jaco0797
Copy link

jaco0797 commented Mar 19, 2019

As the title states, arrowhead edges do not point properly for all directed graphs... at least mine. Their lengths and direction are off. The dimensions of my graph are width = 900, height = 400. Arrowhead_length = 0.01. See attachment. Can the arrowhead edge length and size be dependent on the edge they are associated with instead of the size of the total plot?
ugly arrowheads

@cbarokk
Copy link

cbarokk commented Aug 22, 2019

When xrange is low, the arrows get displayed correctly. This is ok. (1st attachment)

x = [1,2,3,4]
y = [1,2,3,4]
node_indexes = np.arange(4)
node_indexes
nodes = hv.Nodes((x, y, node_indexes, node_indexes))
source,target = [0,1,2],[1,2,3]
graph = hv.Graph(((source, target, ), nodes, ))
graph.opts(directed=True, arrowhead_length=0.05)

However, when xrange is high, the arrows get disproportionally long. This is not ok. (2nd attachment)

x = [100,200,300,400]
y = [1,2,3,4]
node_indexes = np.arange(4)
node_indexes
nodes = hv.Nodes((x, y, node_indexes, node_indexes))
source,target = [0,1,2],[1,2,3]
graph = hv.Graph(((source, target, ), nodes, ))
graph.opts(directed=True, arrowhead_length=0.05)

When x axis is Datetime, then the graph is not displayed.

from datetime import datetime, timedelta
now = datetime.now()
x = [now + timedelta(days=i) for i in [1,2,3,4]]
y = [1,2,3,4]
node_indexes = np.arange(4)
node_indexes
nodes = hv.Nodes((x, y, node_indexes, node_indexes))
source,target = [0,1,2],[1,2,3]
graph = hv.Graph(((source, target, ), nodes, ))
graph

However displaying edges and nodes separately works. (3rd attachment)
graph.edgepaths * graph.nodes

But calling
graph.opts(directed=True, arrowhead_length=0.05)
gives a

TypeError: ufunc 'hypot' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

@cbarokk
Copy link

cbarokk commented Aug 22, 2019

bokeh_plot
bokeh_plot (1)
bokeh_plot (2)

@philippjfr
Copy link
Member

The way arrows are drawn is really not ideal and it would be great if we could switch to using the arrow annotation in bokeh but that's not currently looking too promising since it doesn't support many of the style mapping features we'd need.

@jbednar
Copy link
Member

jbednar commented Aug 22, 2019

I don't suppose Bokeh offers the ability to draw lines whose lengths and angles are specified in screen coordinates (pixels) but anchored on one end at a location in data coordinates?

@poplarShift
Copy link
Collaborator

I think Rays (https://bokeh.pydata.org/en/latest/docs/reference/models/glyphs/ray.html) would fit the bill, I used those for #3504.

@jbednar
Copy link
Member

jbednar commented Aug 22, 2019

Interesting. The length of a Ray says that it defaults to data coordinates, which suggests that there must be a way to specify it in screen coordinates? The angle doesn't seem to specify what coordinates it's in, but I guess it's in screen coordinates? If so then that seems like it would work and would avoid this problem.

@cbarokk
Copy link

cbarokk commented Aug 23, 2019

Are you guys gonna work on it anytime soon?
Or do we, users, have to figure out if the Ray approach is feasible?

@poplarShift
Copy link
Collaborator

poplarShift commented Aug 23, 2019

@jbednar Yup, if I understand the docs correctly (https://bokeh.pydata.org/en/latest/docs/reference/core/properties.html#bokeh.core.properties.DistanceSpec) then distances can be given in data or screen units.

@jbednar
Copy link
Member

jbednar commented Aug 23, 2019

It's open source; we are all both users and developers potentially. :-) I can't speak for all other users, but it's not something on my personal to-do list. Seems fun to play around with, if anyone does get time!

@poplarShift
Copy link
Collaborator

poplarShift commented Aug 23, 2019

There is this PR by me #3653 where I started using bokeh's Arrow for vectorfield (and hence potentially the graphs), but as @philippjfr pointed out there are less style options, so that doesn't look too promising at the moment.

I'm not sure if it's worth first checking out whether or not to enhance the Arrow style options on the bokeh side. Drawing the arrowheads with Ray looks like a better option to me than what is being done now, but it's still a workaround.

Personally, it doesn't presently look like I'll have a lot of vector fields to plot in the near future so I doubt I'll be spending a lot of time with this anytime soon.

Edit: As a side note, all this is about the bokeh interface. The matplotlib interface should deal a lot better with arrows.

@gpo-atlas
Copy link

Any update on this issue?

@hosford42
Copy link

There is also the issue that the arrow heads terminate at the centers of the nodes, rather than radius distance from them. So if you need a larger radius for the nodes, the arrow heads are chopped off.

@hosford42
Copy link

As a workaround for the misshapen arrow heads, you can set graph.opts(aspect='equal'). The arrow heads are then drawn correctly, at the expense of the graph coordinate axes being restricted to precisely equal aspect ratio.

@hosford42
Copy link

This is actually a strong clue as to why the arrow heads are misshapen to begin with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants