我熟悉以下问题:
Matplotlib savefig,在绘图外带有图例
如何把传说从情节中剔除
这些问题的答案似乎有一种奢侈,能够摆弄轴的精确收缩,以便传说符合。
然而,缩小轴并不是一个理想的解决方案,因为它使数据更小,实际上更难解释;特别是当它很复杂而且有很多事情发生的时候。。。因此需要一个大的传说
文档中复杂图例的示例说明了这一点的必要性,因为其绘图中的图例实际上完全掩盖了多个数据点。
http://matplotlib.sourceforge.net/users/legend_guide.html#legend-复杂地块的划分
我希望能够做的是动态扩展图形框的大小,以适应不断扩展的图形图例。
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-2*np.pi, 2*np.pi, 0.1)
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(x, np.sin(x), label='Sine')
ax.plot(x, np.cos(x), label='Cosine')
ax.plot(x, np.arctan(x), label='Inverse tan')
lgd = ax.legend(loc=9, bbox_to_anchor=(0.5,0))
ax.grid('on')
最后,我被告知这在R和LaTeX中是正常的行为,所以我有点困惑为什么在python中如此困难。。。有历史原因吗?Matlab在这件事上同样糟糕吗?
我在pastebin上有这个代码的(只是稍微长一点)版本http://pastebin.com/grVjc007
这里还有一个非常手动的解决方案。您可以定义轴的大小,并相应地考虑衬垫(包括图例和刻度)。希望它对某人有用。
示例(轴大小相同!):
代码:
#==================================================
# Plot table
colmap = [(0,0,1) #blue
,(1,0,0) #red
,(0,1,0) #green
,(1,1,0) #yellow
,(1,0,1) #magenta
,(1,0.5,0.5) #pink
,(0.5,0.5,0.5) #gray
,(0.5,0,0) #brown
,(1,0.5,0) #orange
]
import matplotlib.pyplot as plt
import numpy as np
import collections
df = collections.OrderedDict()
df['labels'] = ['GWP100a\n[kgCO2eq]\n\nasedf\nasdf\nadfs','human\n[pts]','ressource\n[pts]']
df['all-petroleum long name'] = [3,5,2]
df['all-electric'] = [5.5, 1, 3]
df['HEV'] = [3.5, 2, 1]
df['PHEV'] = [3.5, 2, 1]
numLabels = len(df.values()[0])
numItems = len(df)-1
posX = np.arange(numLabels)+1
width = 1.0/(numItems+1)
fig = plt.figure(figsize=(2,2))
ax = fig.add_subplot(111)
for iiItem in range(1,numItems+1):
ax.bar(posX+(iiItem-1)*width, df.values()[iiItem], width, color=colmap[iiItem-1], label=df.keys()[iiItem])
ax.set(xticks=posX+width*(0.5*numItems), xticklabels=df['labels'])
#--------------------------------------------------
# Change padding and margins, insert legend
fig.tight_layout() #tight margins
leg = ax.legend(loc='upper left', bbox_to_anchor=(1.02, 1), borderaxespad=0)
plt.draw() #to know size of legend
padLeft = ax.get_position().x0 * fig.get_size_inches()[0]
padBottom = ax.get_position().y0 * fig.get_size_inches()[1]
padTop = ( 1 - ax.get_position().y0 - ax.get_position().height ) * fig.get_size_inches()[1]
padRight = ( 1 - ax.get_position().x0 - ax.get_position().width ) * fig.get_size_inches()[0]
dpi = fig.get_dpi()
padLegend = ax.get_legend().get_frame().get_width() / dpi
widthAx = 3 #inches
heightAx = 3 #inches
widthTot = widthAx+padLeft+padRight+padLegend
heightTot = heightAx+padTop+padBottom
# resize ipython window (optional)
posScreenX = 1366/2-10 #pixel
posScreenY = 0 #pixel
canvasPadding = 6 #pixel
canvasBottom = 40 #pixel
ipythonWindowSize = '{0}x{1}+{2}+{3}'.format(int(round(widthTot*dpi))+2*canvasPadding
,int(round(heightTot*dpi))+2*canvasPadding+canvasBottom
,posScreenX,posScreenY)
fig.canvas._tkcanvas.master.geometry(ipythonWindowSize)
plt.draw() #to resize ipython window. Has to be done BEFORE figure resizing!
# set figure size and ax position
fig.set_size_inches(widthTot,heightTot)
ax.set_position([padLeft/widthTot, padBottom/heightTot, widthAx/widthTot, heightAx/heightTot])
plt.draw()
plt.show()
#--------------------------------------------------
#==================================================
补充:我找到了一些可以马上完成这个技巧的东西,但是下面的代码也提供了一个替代方案。
使用subplots_adjust()
函数向上移动子情节的底部:
fig.subplots_adjust(bottom=0.2) # <-- Change the 0.02 to work for your plot.
然后在legend命令的legendbbox\u to\u anchor
部分中使用偏移量,以获得所需的legend框。设置figsize
和使用子批次调整(底部=…)的一些组合
应该为您生成质量图。
备选方案:我只是简单地更改了行:
fig = plt.figure(1)
致:
fig = plt.figure(num=1, figsize=(13, 13), dpi=80, facecolor='w', edgecolor='k')
并且改变了
lgd = ax.legend(loc=9, bbox_to_anchor=(0.5,0))
到
lgd = ax.legend(loc=9, bbox_to_anchor=(0.5,-0.02))
它在我的屏幕上显示得很好(一个24英寸的CRT显示器)。
这里
figsize=(M, N)
将图形窗口设置为M英寸乘N英寸。玩这个,直到它看起来适合你。将其转换为更可缩放的图像格式,并在必要时使用GIMP进行编辑,或者在包含图形时仅使用LaTeXviewport
选项进行裁剪。
抱歉,EMS,但实际上我刚刚从matplotlib邮件列表中得到另一个回复(感谢Benjamin Root)。
我正在寻找的代码正在将Savefig调用调整为:
fig.savefig('samplefigure', bbox_extra_artists=(lgd,), bbox_inches='tight')
#Note that the bbox_extra_artists must be an iterable
这显然类似于调用tight_layout,但是您允许Savefig在计算中考虑额外的艺术家。事实上,这确实根据需要调整了图形框的大小。
import matplotlib.pyplot as plt
import numpy as np
plt.gcf().clear()
x = np.arange(-2*np.pi, 2*np.pi, 0.1)
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(x, np.sin(x), label='Sine')
ax.plot(x, np.cos(x), label='Cosine')
ax.plot(x, np.arctan(x), label='Inverse tan')
handles, labels = ax.get_legend_handles_labels()
lgd = ax.legend(handles, labels, loc='upper center', bbox_to_anchor=(0.5,-0.1))
text = ax.text(-0.2,1.05, "Aribitrary text", transform=ax.transAxes)
ax.set_title("Trigonometry")
ax.grid('on')
fig.savefig('samplefigure', bbox_extra_artists=(lgd,text), bbox_inches='tight')
这就产生了:
[编辑]这个问题的目的是完全避免使用任意文本的任意坐标放置,这是解决这些问题的传统方法。尽管如此,最近的许多编辑坚持要把这些放进去,通常会导致代码出错。现在,我已经修复了这些问题,并整理了任意文本,以展示如何在bbox_extra_算法中考虑这些问题。
绘制一个圆环图,轴外有两个图例(第一个图例-在图形右侧,第二个-在底部)。 通过考虑两个图例的尺寸,对图形进行紧凑布局。
我做错了什么?
我在用图表。js 2.9。4和ng2图表包装器的角度。我试图显示传入的实时数据,但在配置图表时遇到问题,因此刻度/轴不会超出图表中的数据。换句话说,我希望图表数据点填充图表网格的整个宽度。 StackBlitz显示了我的问题。 如果您在添加数据时一直查看图表,您会发现大多数时间刻度都会延伸到图表中的最后一点之外: 我能想到的唯一解决方案是每次向图表中添加新数据时覆盖x轴上刻度的最大值:
在一些应用场景中,有时需要绘制两个 x 轴或两个 y 轴,这样可以更直观地显现图像,从而获取更有效的数据。Matplotlib 提供的 twinx() 和 twiny() 函数,除了可以实现绘制双轴的功能外,还可以使用不同的单位来绘制曲线,比如一个轴绘制对函数,另外一个轴绘制指数函数。 下面示例绘制了一个具有两个 y 轴的图形,一个显示指数函数 exp(x),另一个显示对数函数 log(x)。 输
我正在使用一个创建的多行图,该图具有这样一个延伸到图形边界之外的外部图例。 我的: 不幸的是,在使用和命令下载图形时,图例从导出的图像中被切掉。 使用此Colab Link(在最后一个单元格中),您可以更清楚地看到问题。 请提出解决方案。
问题内容: 阅读以下文章,我设法将图例放在情节之外。 如何将图例排除在情节之外 码: 显示正确的绘图,并在其外部带有图例。但是,当我使用将文件另存为文件时,图例将被截断。 一些谷歌搜索显示了变通方法,例如add或to ,但都没有用。 正确的方法是什么?Matplotlib版本是0.99.3。 谢谢。 问题答案: 问题是,当您动态绘图时,会自动确定边框以适合所有对象。保存文件时,操作不会自动完成,因