我试图在matplotlib中的情节之外放置一个相当广泛的传说。图例有很多条目,每个条目都可能很长(但我不知道确切的长度)。
显然这很好用
legendHandle = plt.legend(loc = "center left", bbox_to_anchor = (1, 0.5))
但问题是,图例被窗口的边缘切断了。我花了很长时间寻找解决方案。到目前为止,我能找到的最好的东西是:
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
plt.legend(loc = "center left", bbox_to_anchor = (1, 0.5))
不幸的是,这并没有真正解决我的问题。由于应用于框宽度的显式因子0.8,这只适用于图形和图例宽度的一个特定组合。如果我调整图形窗口的大小,或者如果我的图例条目有不同的长度,它就不起作用。
我只是不明白在人物之外放置一个图例怎么会如此困难。我习惯了Matlab,它很简单
legend('Location', 'eastoutside')
Python中有没有类似的东西我错过了?
图例的放置可以通过使用参数loc和bbox_to_锚来控制。下面是一个代码示例:
import matplotlib.pyplot as plt
#sample data
import numpy as np
x = np.linspace(0, 2, 101)
#create figure and its axes
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
#plot 3 lines and define their labels
ax.plot(x, x**2, label="square")
ax.plot(x, x**3, label="cubic")
ax.plot(x, np.sin(x), label="sinus")
#place the legend
ax.legend(loc='lower center', bbox_to_anchor=(0.5, 1.0), ncol=3)
# The center of the lower edge of the rectangle containing the legend
# is placed at coordinates (x,y)=(0.5,1.0) of ax.
# Thus, figure and legend should not overlap.
plt.show()
现在您应该看到下图:图例在外的图
刚刚偶然发现这个问题,我想你可以使用人物的图例方法:
import matplotlib.pyplot as plt
# sample data
x1 = [1,2,3,4,5,6]
y1 = [0,1,0,1,0,1]
x2 = [1,2,3,4,5,6]
y2 = [9,8,8,7,8,6]
fig = plt.figure(figsize=(4, 2), dpi=100)
ax = fig.add_subplot(111)
ax.plot(x1,y1,x2,y2)
fig.legend(loc=1, mode='expand', numpoints=1, ncol=4, fancybox = True,
fontsize='small', labels=['d1', 'd2'])
# loc=1 means at the top-right of the figure
plt.show()
尽管图例位于轴的外部,但如果图例太大,它仍可能与轴重叠。
在尝试了很多之后,这是我能想到的最好的:
from matplotlib.lines import Line2D
from matplotlib.gridspec import GridSpec
from enum import Enum
class Location(Enum):
EastOutside = 1
WestOutside = 2
NorthOutside = 3
SouthOutside = 4
class Legend:
def __init__(self, figure, plotAxes, location: Location):
self.figure = figure
self.plotAxes = plotAxes
self.location = location
# Create a separate subplot for the legend. Actual location doesn't matter - will be modified anyway.
self.legendAxes = figure.add_subplot(1, 2, 1)
self.legendAxes.clear() # remove old lines
self.legendAxes.set_axis_off()
# Add all lines from the plot to the legend subplot
for line in plotAxes.get_lines():
legendLine = Line2D([], [])
legendLine.update_from(line)
self.legendAxes.add_line(legendLine)
if self.location == Location.EastOutside:
self.legend = self.legendAxes.legend(loc = "center left")
elif self.location == Location.WestOutside:
self.legend = self.legendAxes.legend(loc = "center right")
elif self.location == Location.NorthOutside:
self.legend = self.legendAxes.legend(loc = "lower center")
elif self.location == Location.SouthOutside:
self.legend = self.legendAxes.legend(loc = "upper center")
else:
raise Exception("Unknown legend location.")
self.UpdateSize()
# Recalculate legend size if the size changes
figure.canvas.mpl_connect('resize_event', lambda event: self.UpdateSize())
def UpdateSize(self):
self.figure.canvas.draw() # draw everything once in order to get correct legend size
# Extract legend size in percentage of the figure width
legendSize = self.legend.get_window_extent().inverse_transformed(self.figure.transFigure)
legendWidth = legendSize.width
legendHeight = legendSize.height
# Update subplot such that it is only as large as the legend
if self.location == Location.EastOutside:
gridspec = GridSpec(1, 2, width_ratios = [1 - legendWidth, legendWidth])
legendLocation = 1
plotLocation = 0
elif self.location == Location.WestOutside:
gridspec = GridSpec(1, 2, width_ratios = [legendWidth, 1 - legendWidth])
legendLocation = 0
plotLocation = 1
elif self.location == Location.NorthOutside:
gridspec = GridSpec(2, 1, height_ratios = [legendHeight, 1 - legendHeight])
legendLocation = 0
plotLocation = 1
elif self.location == Location.SouthOutside:
gridspec = GridSpec(2, 1, height_ratios = [1 - legendHeight, legendHeight])
legendLocation = 1
plotLocation = 0
else:
raise Exception("Unknown legend location.")
self.legendAxes.set_position(gridspec[legendLocation].get_position(self.figure))
self.legendAxes.set_subplotspec(gridspec[legendLocation]) # to make figure.tight_layout() work if that's desired
self.plotAxes.set_position(gridspec[plotLocation].get_position(self.figure))
self.plotAxes.set_subplotspec(gridspec[plotLocation]) # to make figure.tight_layout() work if that's desired
这使得我到目前为止测试的案例中的图例或多或少是正确的。用法是。
import matplotlib.pyplot as plt
plt.ion()
figure = plt.figure()
plotAxes = figure.gca()
plotAxes.plot([1, 2, 3], [4, 5, 6], "b-", label = "Testaaaaaaaaaaaaaa 1")
plotAxes.plot([1, 2, 3], [6, 5, 4], "r-", label = "Test 2")
legend = Legend(figure, plotAxes, Location.EastOutside)
让我问一下我已经在评论中发布的问题...我将如何建议将此作为matplotlib开发人员的附加功能?(不是我的黑客,而是一种在人物之外拥有传奇的原生方式)
我想把线条图和标记的标签都标成红色。然而,这个传说并没有出现,因为它的情节占用了它的空间。 使现代化 原来我不能在 我使用以下方法使数字变大: 但是,现在图例中只有一个标签,标记显示在线形图上,而我更希望有两个:一个单独用于标记,另一个单独用于线条: 更新代码:
问题内容: 我在matplotlib中有一个简单的绘图,我想增加标题和绘图之间的距离(不使用,因为它不适用于我在服务器上使用的版本)。怎么做 ? 问题答案: 似乎没有一种直接设置此设置的干净方法(但是可能需要添加功能请求),但是标题只是一个艺术家,因此您可以深入并进行更改。 应该可以。根据自己的喜好进行调整。
问题内容: 我是python的新手,我开始使用以下链接的练习来教自己如何在jupyter上使用熊猫: http://nbviewer.jupyter.org/github/jvns/pandas- cookbook/blob/v0.1/cookbook/Chapter%201%20-%20Reading%20from%20a%20CSV.ipynb 我有一个问题,当我在Jupyter中进行操作时,
本文向大家介绍跟老齐学Python之传说中的函数编写条规,包括了跟老齐学Python之传说中的函数编写条规的使用技巧和注意事项,需要的朋友参考一下 关于函数的事情,总是说不完的,下面就罗列一些编写函数的注意事项。特别声明,这些事项不是我总结的,我是从一本名字为《Learning Python》的书里面抄过来的,顺便写成了汉语,当然,是按照自己的视角翻译的,里面也夹杂了一些自己的观点。看官也可以理解
问题内容: 我要在一个图形中制作一系列20个图(不是子图)。我希望图例在框外。同时,由于图形尺寸变小,我不想更改轴。请帮助我进行以下查询: 我想将图例框保留在绘图区域之外。(我希望图例位于绘图区域的右侧)。 无论如何,我是否减小了图例框内文本的字体大小,以使图例框的大小变小。 问题答案: 有很多方法可以做你想要的。要添加和所说的内容,可以使用关键字参数将图例部分地放置在轴外and/or 减小字体大
当我在spyder中使用pandas绘图数据时。它将始终显示一条警告消息: C:\ProgramData\Anaconda3\lib\site packages\pandas\core\index。py:494:SettingWithCopyWarning:试图在数据帧切片的副本上设置值。尝试使用。loc[row\u indexer,col\u indexer]=改为value。请参阅文档中的注意