簡體   English   中英

Matplotlib也在情節之外擴展了最佳定位

[英]Matplotlib extend best positioning also outside the plot

我試圖繪制幾個數據,在某些情況下,占據整個情節。

版本2的默認選項應該是“最佳”,它會嘗試找到將圖例放置在圖中的最佳位置。 有沒有辦法擴展選項,以便在空間不足的情況下將圖例放在圖表之外?

否則,matplotlib是否有一個選項(不占用所有系列的最大值並添加手動填充)以自動添加ylim填充並為圖例提供空間並放置在繪圖內?

主要思想是避免手動調整繪圖,自動創建多個繪圖。

簡單的MWE如下:

%matplotlib inline
%config InlineBackend.figure_format = 'svg'
import scipy as sc
import matplotlib.pyplot as plt
plt.close('all')

x = sc.linspace(0, 1, 50)
y = sc.array([sc.ones(50)*0.5, x, x**2, (1-x), (1-x**2)]).T
fig = plt.figure('Fig')
ax = fig.add_subplot(111)
lines = ax.plot(x, y)
leg = ax.legend([lines[0], lines[1], lines[2], lines[3], lines[4]],
                [r'$\mathrm{line} = 0.5$', r'$\mathrm{line} = x$', r'$\mathrm{line} = x^2$',
                 r'$\mathrm{line} = 1-x$',r'$\mathrm{line} = 1-x^2$'], ncol=2)
fig.tight_layout()

情節

沒有自動方式將圖例放置在軸外的“最佳”位置。

在情節內

您可能決定始終在軸內留出足夠的空間 ,以使圖例不會與任何東西重疊。 為此你可以使用ax.margins 例如

ax.margins(y=0.25)

將在y軸的兩端產生25%的余量,如果它有3列,則有足夠的空間來托管圖例。

在此輸入圖像描述

然后,您可以決定始終使用相同的位置,例如loc="upper center" ,以獲得所有圖表中的一致結果。 這樣做的缺點在於它取決於圖形尺寸,並且它還在軸的另一端添加(可能不期望的)邊緣。 如果您可以使用該保證金,則自動確定所需保證金的方法如下:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.transforms

x = np.linspace(0, 1, 50)
y = np.array([np.ones(50)*0.5, x, x**2, (1-x), (1-x**2)]).T
fig = plt.figure('Fig')
ax = fig.add_subplot(111)
lines = ax.plot(x, y)

def legend_adjust(legend, ax=None ):
    if ax == None: ax  =plt.gca()
    ax.figure.canvas.draw()
    bbox = legend.get_window_extent().transformed(ax.transAxes.inverted() )
    print bbox.height
    ax.margins(y = 2.*bbox.height)

leg = plt.legend(handles=[lines[0], lines[1], lines[2], lines[3], lines[4]],
       labels= [r'$\mathrm{line} = 0.5$', r'$\mathrm{line} = x$', r'$\mathrm{line} = x^2$',
                 r'$\mathrm{line} = 1-x$',r'$\mathrm{line} = 1-x^2$'], loc="upper center", 
                  ncol=2)
legend_adjust(leg)
plt.show()

如果設置限制很好,您也可以自行調整限制:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.transforms

x = np.linspace(0, 1, 50)
y = np.array([np.ones(50)*0.5, x, x**2, (1-x), (1-x**2)]).T
fig = plt.figure('Fig')
ax = fig.add_subplot(111)
lines = ax.plot(x, y)

def legend_adjust(legend, ax=None, pad=0.05 ):
    if ax == None: ax  =plt.gca()
    ax.figure.canvas.draw()
    bbox = legend.get_window_extent().transformed(ax.transAxes.inverted() )
    ymin, ymax = ax.get_ylim()
    ax.set_ylim(ymin, ymax+(ymax-ymin)*(1.+pad-bbox.y0))



leg = plt.legend(handles=[lines[0], lines[1], lines[2], lines[3], lines[4]],
       labels= [r'$\mathrm{line} = 0.5$', r'$\mathrm{line} = x$', r'$\mathrm{line} = x^2$',
                 r'$\mathrm{line} = 1-x$',r'$\mathrm{line} = 1-x^2$'], loc="upper center", 
                  ncol=2)
legend_adjust(leg)
plt.show()

在此輸入圖像描述

走出陰謀

否則,您可能決定始終將圖例放在圖表之外 這個答案中收集了一些技術。

特別感興趣的可能是將圖例放在圖形外部而不更改圖形,如本問題所述: 創建具有精確尺寸且沒有填充的圖形(以及軸外的圖例)

使其適應這種情況看起來像:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.transforms

x = np.linspace(0, 1, 50)
y = np.array([np.ones(50)*0.5, x, x**2, (1-x), (1-x**2)]).T
fig = plt.figure('Fig')
ax = fig.add_subplot(111)
lines = ax.plot(x, y)

def legend(ax=None, x0=1,y0=1, direction = "v", padpoints = 3,**kwargs):
    if ax == None: ax  =plt.gca()
    otrans = ax.figure.transFigure
    t = ax.legend(bbox_to_anchor=(x0,y0), loc=1, bbox_transform=otrans,**kwargs)
    plt.tight_layout()
    ax.figure.canvas.draw()
    plt.tight_layout()
    ppar = [0,-padpoints/72.] if direction == "v" else [-padpoints/72.,0] 
    trans2=matplotlib.transforms.ScaledTranslation(ppar[0],ppar[1],fig.dpi_scale_trans)+\
             ax.figure.transFigure.inverted() 
    tbox = t.get_window_extent().transformed(trans2 )
    bbox = ax.get_position()
    if direction=="v":
        ax.set_position([bbox.x0, bbox.y0,bbox.width, tbox.y0-bbox.y0]) 
    else:
        ax.set_position([bbox.x0, bbox.y0,tbox.x0-bbox.x0, bbox.height]) 

legend(handles=[lines[0], lines[1], lines[2], lines[3], lines[4]],
       labels= [r'$\mathrm{line} = 0.5$', r'$\mathrm{line} = x$', r'$\mathrm{line} = x^2$',
                 r'$\mathrm{line} = 1-x$',r'$\mathrm{line} = 1-x^2$'], 
                 y0=0.8, direction="h", borderaxespad=0.2)

plt.show()

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM