【发布时间】:2018-05-12 09:15:11
【问题描述】:
我正在开发一个程序,该程序允许用户在轴上放置不同数量的图。我需要显示图例,而且情节标签很长,所以我认为最好在情节下显示这个。当我以前这样做的时候,我总是把情节缩小一点,把图例放在情节下面。现在有不同数量的图,这并不那么简单,因为我找不到一个很好的公式来确定将图缩小多少以及将图例放多远,这样它就不会被切断或重叠轴。
我编写了一个示例代码来演示我目前正在做的事情,这很难看。我目前正在检查图中有多少项目,并尝试手动优化轴收缩和图例偏移参数,然后做了一个大的if 循环以使用手动优化的值。它们没有针对此示例代码进行优化,但我认为它演示了我在做什么。
import matplotlib.pyplot as plt
import numpy as np
def find_scales(legendData):
leg_len = len(legendData)
if leg_len == 0:
height_scale = 1
legend_offset = 0
elif leg_len == 1:
height_scale = 0.96
legend_offset = -0.18
elif leg_len == 2:
height_scale = 0.95
legend_offset = -0.25
elif leg_len == 3:
height_scale = 0.94
legend_offset = -0.35
elif leg_len == 4:
height_scale = 0.93
legend_offset = -0.45
elif leg_len == 5:
height_scale = 0.93
legend_offset = -0.57
elif leg_len == 6:
height_scale = 0.93
legend_offset = -0.68
elif leg_len == 7:
height_scale = 0.93
legend_offset = -0.82
elif leg_len == 8:
height_scale = 0.93
legend_offset = -0.98
elif leg_len == 9:
height_scale = 0.92
legend_offset = -1.3
elif leg_len == 10:
height_scale = 0.92
legend_offset = -1.53
else:
height_scale = 0.92
legend_offset = -1.8
return height_scale, legend_offset
num_plots = 3
x_range = np.arange(10)
fig,ax = plt.subplots()
for i in range(num_plots):
ax.plot(x_range, np.random.rand(10))
legend_labels = ['a','b','c','d','e','f','g','h','i','j'][:num_plots]
box = ax.get_position()
height_scale, legend_offset = find_scales(legend_labels)
ax.set_position([box.x0, box.y0 + box.height * (1-height_scale), #left, bottom, width, height
box.width, box.height * height_scale])
ax.legend(legend_labels, loc=3, bbox_to_anchor=(0,legend_offset), borderaxespad=0.)
plt.show()
我希望有更好的方法来做到这一点。我希望图例位于轴下方。我不能让图例与轴或 x 标签重叠。我不能因为太低和不合身而让传说被切断。有没有办法让轴和图例自动调整大小以适应图形?
【问题讨论】:
-
您(几乎)线性缩放
height_scale和legend_offset作为leg_len的函数)。因此,只需编写一个为您计算它们的函数并丢弃所有if/elif块。 -
我猜○this question 的答案是你想要的(它只是把图例放在上面而不是下面)。
-
@PaulH 我花时间试图找到一个缩放函数,但它似乎比线性缩放函数更复杂,这就是我需要具体计算每个案例的原因。
-
@wwii 这是我工作的帖子。它没有解决图例中项目数量可变的问题。
标签: python matplotlib