-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Using arrows in draw_networkx_edges removes legend labels. #7054
Comments
Thanks for the report. |
Yeah I don't know if there's a way to do this generally in matplotlib. My (admittedly limited) understanding is that not all matplotlib artists are supported as legend handles. I suspect that Assuming the above is correct (again, I'm not 100% sure that patches can't be legend handles --- it's worth investigating further) my vote would be to add an example for this to the networkx gallery. |
This info was quite helpful for me -- thank you! I discovered:
Here's my idea:
lin = mlines.Line2D([], [], color=b[0].get_edgecolor(), linestyle=b[0].get_linestyle(), label=label) I have written this as if the list
Then when the user does plt.clf()
g=nx.path_graph(4)
pos = {i: (i,i) for i in g}
ax=plt.gca()
n = nx.draw_networkx_nodes(g, pos, label="nodes")
c = nx.draw_networkx_edges(g, pos, [(0, 1)], style='solid', label="edge2")
b = nx.draw_networkx_edges(g, pos, [(1,2), (2,3)], style = 'dashed', edge_color="blue", arrows=True, arrowstyle='-|>')
lin = mlines.Line2D([], [], color=b[0].get_edgecolor(), linestyle=b[0].get_linestyle(), label='edge1')
# user does this
ax.add_artist(lin) |
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
g = nx.Graph()
g.add_nodes_from((1, 2, 3))
g.add_edges_from(((1, 2), (2, 3)))
pos = nx.spring_layout(g)
# Draw edges with arrows and labels
nx.draw_networkx_edges(g, pos, [(1, 2)], label="edge1", style='dashed', arrows=True, arrowstyle='-|>')
nx.draw_networkx_edges(g, pos, [(2, 3)], label="edge2", style='solid')
nx.draw_networkx_nodes(g, pos, label="nodes")
# Create sets for legend handles and labels
legend_handles = set()
legend_labels = set()
# Iterate over edges and add legend entries dynamically
for edge in g.edges():
edge_label = f"edge_{edge[0]}_{edge[1]}" # You can modify this based on your requirements
if edge_label not in legend_labels:
linestyle = 'dashed' if edge in [(1, 2)] else 'solid' # Choose linestyle based on conditions
lin_edge = mlines.Line2D([], [], color='black', linestyle=linestyle, label=edge_label)
legend_handles.add(lin_edge)
legend_labels.add(edge_label)
# Extract existing legend handles and labels
ax = plt.gca()
existing_handles, existing_labels = ax.get_legend_handles_labels()
# Add existing handles and labels to the sets
legend_handles.update(existing_handles)
legend_labels.update(existing_labels)
# Create a new legend with the combined set
plt.legend(handles=legend_handles, labels=legend_labels)
# Display the plot
plt.show() |
I think the |
When using the
arrows
argument in networkx.draw_networkx_edges, legend labels are removed from the object so they don't show up in the legend.Current Behavior
Passing
arrows=True
removes the edge from the legend.Expected Behavior
If a legend label is passed, it should be shown if you use
plt.legend()
.Steps to Reproduce
Gives the following plot with broken legend:
This is what would have been shown if
arrows=True
was not passed:Environment
Anaconda Python (Windows)
Python version: 3.10.9
NetworkX version: 3.1
The text was updated successfully, but these errors were encountered: