I'm trying to have one large plot, and then use arrows to connect outliers to smaller plots. I used gridspec to create my plots, and on their own they show up perfectly.
However, when I try to use ConnectionPatch to add an artist for the arrows, it changes the size of all the subplots.
Here is my code setting up the figure and subplots using gridspec:
fig2 = plt.figure(constrained_layout=True)
gs = fig2.add_gridspec(ncols=3, nrows=9, figure=fig2)
f2_ax1 = fig2.add_subplot(gs[0:-4, :-1])
f2_ax2 = fig2.add_subplot(gs[2:-4, 2])
f2_ax3 = fig2.add_subplot(gs[5:-1, 0])
f2_ax4 = fig2.add_subplot(gs[5:-1, 1])
f2_ax5 = fig2.add_subplot(gs[5:-1,2])
This creates the plots I want (see picture):
Here is how I'm adding arrows to the plots, using a for loop to iterate through each subplot:
coordsA = "data" #The arrows are plotting using the same coordinates as the data points
coordsB = "data"
i = 0
for sub_plot in sub_plot_list: #Adding the arrows to the subplots
xy1 = (x_oulier_list[i], y_outlier_list[i]) #Fetches coordinates for beginning of arrow
xy2 = arrow_end_list[i] #Fetches coordinates for the pointy end of arrow
con = ConnectionPatch(xyA=(x_outlier_list[i],y_outlier_list[i]), xyB=arrow_end_list[i],
coordsA=coordsA, coordsB=coordsB,
axesA=f2_ax1, axesB=sub_plot,
arrowstyle="->", shrinkB=5)
f2_ax1.add_artist(con) #Adds arrow to plot
i += 1
Both versions use fig2.tight_layout()
.
Here is the plot after adding arrows:
Any idea how I can fix it so that the dimensions of the plot don't change when I add arrows?
Looks like the problem is with constrained_layout
, which does not seem to handle ConnectionPatch
very well (constrained_layout
is still experimental, maybe it is worth raising an issue on matplotlib's github in case someone can figure the problem out).
An easy fix is to request that the ConnectionPatch objects are not taken into account when calculating the layout using:
(...)
con = ConnectionPatch(xyA=(x_outlier_list[i],y_outlier_list[i]), xyB=arrow_end_list[i],
coordsA=coordsA, coordsB=coordsB,
axesA=f2_ax1, axesB=sub_plot,
arrowstyle="->", shrinkB=5)
con.set_in_layout(False)
(...)