如何从子图中完全删除图并适当调整大小?
How to fully delete plots from subplot and properly resize?
我正在尝试为即将发表的论文创建角图,但 运行 遇到了困难。我正在创建一个 N x N 子图数组(目前,N = 6),然后删除其中一半以上的子图。问题是,在我删除无关的子图后,该图似乎没有自行调整大小,因此当我稍后使用虚拟子图添加图例时,它存在于一整行和一列已删除的子图所在的区域,从而扩大了图。我已经为此工作了几个小时,但还没有找到解决方案。这是 MWE:
import matplotlib.pyplot as plt
%matplotlib notebook
n_char = 8
# Set up the main figure.
fig, ax = plt.subplots(n_char, n_char, figsize=(n_char, n_char))
# Get rid of the axis labels unless it's on the left-most column or bottom-most row.
for i in range(0, n_char):
# For each row, loop over each column.
for j in range(0, n_char):
# If the plot isn't in the bottom-most row, get rid of the x-axis tick labels.
if i != n_char - 1:
ax[i, j].set_xticklabels([])
# If the plot isn't in the left-most column, get rid of the y-axis tick labels.
if j != 0:
ax[i, j].set_yticklabels([])
# Remove the plots that are repetitive or boring (plotting against the same characteristic).
for i in range(0, n_char):
# For each row, loop over each column.
for j in range(0, n_char):
# Delete the offending axes.
if j >= i:
ax[i, j].remove()
# Set the spacing between the plots to a much smaller value.
fig.subplots_adjust(hspace=0.00, wspace=0.00)
# Create a big plot for the legend. Have the frame hidden.
fig.add_subplot(111, frameon=False, xticks=[], yticks=[], xticklabels=[], yticklabels=[])
# Create some dummy data to serve as the source of the legend.
plt.scatter([10], [10], color="k", s=5, zorder=2, label="Targets")
# Set the x-axis limits such that the dummy data point is invisible.
fig.gca().set_xlim(-1, 1)
# Add the legend to the plot. Have it located in the upper right.
plt.legend(scatterpoints=1, loc="upper right", fontsize=5)
# Save the final plot.
fig.savefig("./../Code Output/Other Plots/Corner_Plot_Test.png", bbox_inches="tight", dpi=500)
我在 Stack Overflow 上查看了许多不同的问题。两个最有希望的候选人 , but I found the solution wasn't quite workable due to the large number of plots (and, to be frank, I didn't fully understand the solution). I thought that the first answer in 也可能有效,因为我认为这是一个大小问题(即图形没有调整大小,所以创建一个新的子图就是创建一个与原始图形大小相同的子图),但所有它确实调整了 entire 图形的大小,所以这也不起作用。
为了提供帮助,我还会附上一张图片。我获取了上面代码的输出并对其进行了编辑以显示我想要的内容:
我应该补充一点,如果我 不 添加子图,输出是我预期的(即它是正确的大小),所以问题出现在添加子图,即行 fig.add_subplot(111, frameon=False, xticks=[], yticks=[], xticklabels=[], yticklabels=[])
.
使用GridSpec
可能会有帮助。
GridSpec 用于指定要绘制的轴数组。您可以在选项中将列宽和行高设置为比率。不需要的行应该有很小的高度比,而不需要的列应该有很小的宽度比。
这是可运行的代码和输出图:-
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
#import numpy as np
fig = plt.figure(figsize=(8, 8))
nn = 6
# will create gridspec of 6 rows, 6 columns
# 1st row will occupy v small heights
# last column will occupy v small widths
sm = 0.01 # the v small width/height
wh = (1.-sm)/(nn-1.) # useful width/height
gs = gridspec.GridSpec(nn, nn, width_ratios=[*[wh]*(nn-1), sm], \
height_ratios= [sm, *[wh]*(nn-1)])
cols, rows = nn, nn
ax = [[0 for i in range(cols)] for j in range(rows)]
for ea in range(nn):
for eb in range(nn):
ax[ea][eb] = fig.add_subplot(gs[ea, eb])
ax[ea][eb].set_xticklabels([])
ax[ea][eb].set_yticklabels([])
if eb>=ea:
ax[ea][eb].remove()
# plot data on some axes
# note that axes on the first row (index=0) are gone
ax[2][0].plot([2,5,3,7])
ax[4][2].plot([2,3,7])
# make legend in upper-right axes (GridSpec's first row, last column)
# first index: 0
# second index: nn-1
rx, cx = 0, nn-1
ax[rx][cx] = fig.add_subplot(gs[rx,cx])
hdl = ax[rx][cx].scatter([10], [10], color="k", s=5, zorder=2, label="Targets")
ax[rx][cx].set_axis_off()
#ax[rx][cx].set_visible(True) # already True
ax[rx][cx].set_xticklabels([])
ax[rx][cx].set_yticklabels([])
# plot legend
plt.legend(bbox_to_anchor=(1.0, 1.0), loc='upper right', borderaxespad=0.)
fig.subplots_adjust(hspace=0.00, wspace=0.00)
plt.show
我正在尝试为即将发表的论文创建角图,但 运行 遇到了困难。我正在创建一个 N x N 子图数组(目前,N = 6),然后删除其中一半以上的子图。问题是,在我删除无关的子图后,该图似乎没有自行调整大小,因此当我稍后使用虚拟子图添加图例时,它存在于一整行和一列已删除的子图所在的区域,从而扩大了图。我已经为此工作了几个小时,但还没有找到解决方案。这是 MWE:
import matplotlib.pyplot as plt
%matplotlib notebook
n_char = 8
# Set up the main figure.
fig, ax = plt.subplots(n_char, n_char, figsize=(n_char, n_char))
# Get rid of the axis labels unless it's on the left-most column or bottom-most row.
for i in range(0, n_char):
# For each row, loop over each column.
for j in range(0, n_char):
# If the plot isn't in the bottom-most row, get rid of the x-axis tick labels.
if i != n_char - 1:
ax[i, j].set_xticklabels([])
# If the plot isn't in the left-most column, get rid of the y-axis tick labels.
if j != 0:
ax[i, j].set_yticklabels([])
# Remove the plots that are repetitive or boring (plotting against the same characteristic).
for i in range(0, n_char):
# For each row, loop over each column.
for j in range(0, n_char):
# Delete the offending axes.
if j >= i:
ax[i, j].remove()
# Set the spacing between the plots to a much smaller value.
fig.subplots_adjust(hspace=0.00, wspace=0.00)
# Create a big plot for the legend. Have the frame hidden.
fig.add_subplot(111, frameon=False, xticks=[], yticks=[], xticklabels=[], yticklabels=[])
# Create some dummy data to serve as the source of the legend.
plt.scatter([10], [10], color="k", s=5, zorder=2, label="Targets")
# Set the x-axis limits such that the dummy data point is invisible.
fig.gca().set_xlim(-1, 1)
# Add the legend to the plot. Have it located in the upper right.
plt.legend(scatterpoints=1, loc="upper right", fontsize=5)
# Save the final plot.
fig.savefig("./../Code Output/Other Plots/Corner_Plot_Test.png", bbox_inches="tight", dpi=500)
我在 Stack Overflow 上查看了许多不同的问题。两个最有希望的候选人
为了提供帮助,我还会附上一张图片。我获取了上面代码的输出并对其进行了编辑以显示我想要的内容:
我应该补充一点,如果我 不 添加子图,输出是我预期的(即它是正确的大小),所以问题出现在添加子图,即行 fig.add_subplot(111, frameon=False, xticks=[], yticks=[], xticklabels=[], yticklabels=[])
.
使用GridSpec
可能会有帮助。
GridSpec 用于指定要绘制的轴数组。您可以在选项中将列宽和行高设置为比率。不需要的行应该有很小的高度比,而不需要的列应该有很小的宽度比。
这是可运行的代码和输出图:-
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
#import numpy as np
fig = plt.figure(figsize=(8, 8))
nn = 6
# will create gridspec of 6 rows, 6 columns
# 1st row will occupy v small heights
# last column will occupy v small widths
sm = 0.01 # the v small width/height
wh = (1.-sm)/(nn-1.) # useful width/height
gs = gridspec.GridSpec(nn, nn, width_ratios=[*[wh]*(nn-1), sm], \
height_ratios= [sm, *[wh]*(nn-1)])
cols, rows = nn, nn
ax = [[0 for i in range(cols)] for j in range(rows)]
for ea in range(nn):
for eb in range(nn):
ax[ea][eb] = fig.add_subplot(gs[ea, eb])
ax[ea][eb].set_xticklabels([])
ax[ea][eb].set_yticklabels([])
if eb>=ea:
ax[ea][eb].remove()
# plot data on some axes
# note that axes on the first row (index=0) are gone
ax[2][0].plot([2,5,3,7])
ax[4][2].plot([2,3,7])
# make legend in upper-right axes (GridSpec's first row, last column)
# first index: 0
# second index: nn-1
rx, cx = 0, nn-1
ax[rx][cx] = fig.add_subplot(gs[rx,cx])
hdl = ax[rx][cx].scatter([10], [10], color="k", s=5, zorder=2, label="Targets")
ax[rx][cx].set_axis_off()
#ax[rx][cx].set_visible(True) # already True
ax[rx][cx].set_xticklabels([])
ax[rx][cx].set_yticklabels([])
# plot legend
plt.legend(bbox_to_anchor=(1.0, 1.0), loc='upper right', borderaxespad=0.)
fig.subplots_adjust(hspace=0.00, wspace=0.00)
plt.show