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

Shrink FancyArrowPatch with path parameter #20157

Closed
Adrien-Luxey opened this issue May 4, 2021 · 2 comments
Closed

Shrink FancyArrowPatch with path parameter #20157

Adrien-Luxey opened this issue May 4, 2021 · 2 comments
Labels
Community support Users in need of help.

Comments

@Adrien-Luxey
Copy link

Describe the issue

When calling FancyArrowPatch with the path parameter (instead of posA & posB), the shrink* parameters are not interpreted as defined in the docs:

Alternatively if path is provided, an arrow is drawn along this path and patchA, patchB, shrinkA, and shrinkB are ignored.

However, I can't figure out how to reproduce shrink*'s behavior.

Could anyone provide a solution, please?

Context

I'm writing a PR to improve NetworkX's drawing capabilities, see #4743. For the first time ever, NetworkX would need to draw non-straight edges (composed of straight segments).

Wanting to modify the draw_networkx_edges function as little as possible, I wanted to use FancyArrowPatch as they already do. But I fail to produce an acceptable output because of these arrow heads getting under their target vertex.

Minimal non-working example

import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.path
import numpy as np

# Positions
src = (0, 0)
midpoint = (1, 1)
dst = (2, 0)

# Drawing parameters
node_size = 300
shrink = np.sqrt(node_size) / 2
arrow_kwargs = dict(
    arrowstyle="-|>",
    shrinkA=shrink, shrinkB=shrink,
    mutation_scale=20,
    linewidth=1,
    connectionstyle="arc3",
    color='k', linestyle="solid", 
    zorder=1,
)

fig, ax = plt.subplots()

# Direct arrow
ax.add_patch(
    mpl.patches.FancyArrowPatch(
        posA=src, posB=dst, 
        **arrow_kwargs))

# Path arrow
path = [src, midpoint, dst]
codes = [mpl.path.Path.MOVETO, mpl.path.Path.LINETO, mpl.path.Path.LINETO]
path = mpl.path.Path(path, codes)

ax.add_patch(
    mpl.patches.FancyArrowPatch(
        path=path, 
        **arrow_kwargs))

# Vertices
nodes = np.asarray([src, dst])
ax.scatter(
    nodes[:, 0], nodes[:, 1],
    s=node_size, marker='o',
).set_zorder(2)

ax.tick_params(
    axis="both", which="both",
    bottom=False, left=False,
    labelbottom=False, labelleft=False)
    
plt.show()

mnwe

Pathways

  • Using inside_circle and split_path_inout as done in ConnectionStyle's _shrink method fails with ValueError('The path does not intersect with the patch')
  • I guess computing the path's last position in order to avoid overlap between the arrowhead and the vertex would not be so hard, but I feel like it would burden NetworkX with a brittle solution. I'll do this in last resort.
  • Modifying Matplotlib certainly is a poor solution. Besides, I read you too had difficulties navigating this part of the codebase.

If some of you peoples have a simple solution to provide, it'd be a pleasure. Thanks :)

PS: Be sure I will add my example to Matplotlib's gallery! Usage of FancyArrowPatch with the path parameter is simply missing right now.

@jklymak jklymak added Community support Users in need of help. and removed Maintenance labels May 4, 2021
@jklymak
Copy link
Member

jklymak commented May 4, 2021

The assumption appears to be that if you are specifying the path you are capable of adding the "shrink" yourself. It is pretty hard to algorithmically shrink along an arbitrary user-supplied path.

Since this is working as documented, please discuss at discourse.matplotlib.org. Thanks for your understanding!

@jklymak jklymak closed this as completed May 4, 2021
@Adrien-Luxey
Copy link
Author

Thank you for your reply, I'll head to Discourse. See ya!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community support Users in need of help.
Projects
None yet
Development

No branches or pull requests

2 participants