Networkx In A Subplot Is Drawing Nodes Partially Outside Of Axes Frame
Solution 1:
Background
Your issue seems to be caused by the new autoscaling algorithm introduced with matplotlib
3.2.0. In the link it states, that the old algorithm did
for Axes.scatter it would make the limits large enough to not clip any markers in the scatter.
Hence, the new algorithm has stopped to do this, which results in the cute nodes.
How to fix your problem
You can simply increase the length of your axis:
import networkx as nx
import matplotlib.pylab as plt
figure = plt.subplot(2, 1, 1)
plt.scatter(range(10), range(10))
plt.subplot(2, 1, 2)
G = nx.erdos_renyi_graph(20, p=0.1)
nx.draw_networkx(G)
axis = plt.gca()
# maybe smaller factors work as well, but 1.1 works fine for this minimal example
axis.set_xlim([1.1*x for x in axis.get_xlim()])
axis.set_ylim([1.1*y for y in axis.get_ylim()])
plt.show()
Solution 2:
Just playing a with the figure sizes should do the trick. Try setting a larger figure size through the subplots' figsize
parameter:
f, axs = plt.subplots(2,1,figsize=(15,15))
axs[0].scatter(range(10), range(10))
G = nx.erdos_renyi_graph(20, p=0.1)
nx.draw_networkx(G, ax=axs[1], node_color='lightgreen')
You can also look into networkX' layouts, such as spring_layout
, which allow to encapsulate the nodes within a given box size, specified by a scale
parameter. Here's an example:
f, axs = plt.subplots(2,1,figsize=(15,15))
axs[0].scatter(range(10), range(10))
G = nx.erdos_renyi_graph(20, p=0.05)
pos = nx.spring_layout(G, k=0.7, scale=0.05)
nx.draw_networkx(G, pos=pos, ax=axs[1], node_color='lightgreen')
Solution 3:
Since the other answers require the user to adjust some parameter manually in an iterative process, I wanted to add my own answer. It is automatic, but the current implementation only works if all node sizes are equal.
Node sizes are in points, therefore they don't scale with the image. Although this answer works programmatically, it doesn't work if you interactively change the window size of the figure. The first half of the fix_graph_scale
function calculates the node radius in terms of the future x and y scale. The second half sets the axis scales such that they include all node positions plus half of the node size.
The get_ax_size
function is from unutbu's answer with slight modifications.
import matplotlib.pyplot as plt
import networkx as nx
defget_ax_size(ax):
bbox = ax.get_window_extent().transformed(ax.figure.dpi_scale_trans.inverted())
width, height = bbox.width, bbox.height
width *= 72
height *= 72return width, height
deffix_graph_scale(ax,pos,node_size = 300):
node_radius = (node_size / 3.14159265359)**0.5
min_x = min(i_pos[0] for i_pos in pos.values())
max_x = max(i_pos[0] for i_pos in pos.values())
min_y = min(i_pos[1] for i_pos in pos.values())
max_y = max(i_pos[1] for i_pos in pos.values())
ax_size_x, ax_size_y = get_ax_size(ax)
points_to_x_axis = (max_x - min_x)/(ax_size_x-node_radius*2)
points_to_y_axis = (max_y - min_y)/(ax_size_y-node_radius*2)
node_radius_in_x_axis = node_radius * points_to_x_axis
node_radius_in_y_axis = node_radius * points_to_y_axis
ax_min_x = min_x - node_radius_in_x_axis
ax_max_x = max_x + node_radius_in_x_axis
ax_min_y = min_y - node_radius_in_y_axis
ax_max_y = max_y + node_radius_in_y_axis
ax.set_xlim([ax_min_x, ax_max_x])
ax.set_ylim([ax_min_y, ax_max_y])
fig, (ax1, ax2) = plt.subplots(2, 1)
ax1.scatter(range(10), range(10))
G = nx.erdos_renyi_graph(20, p=0.1)
pos = nx.drawing.spring_layout(G)
nx.draw_networkx(G,pos,ax=ax2)
default_node_size = 300
fix_graph_scale(ax2,pos,node_size = default_node_size)
plt.show()
Post a Comment for "Networkx In A Subplot Is Drawing Nodes Partially Outside Of Axes Frame"