簡體   English   中英

如何在 Matplotlib 中生成嵌套圖例

[英]How to produce nested legends in Matplotlib

我必須在 Matplotlib 中的 plot 一個數量,這是各種貢獻的總和

我想通過將各種貢獻列為主要圖例條目的子元素,在 plot 的圖例中強調這一事實。

我想獲得的結果草圖可以在下面的圖片中找到。 請注意,我不一定要完全實現所描繪的圖例,而只是類似的東西。

您可以嘗試為您的人物創建兩個單獨的圖例。 當然,這是一個技巧,而不是傳說中的 object 的直接功能,因為 matplotlib 中似乎沒有實現您需要的功能。 但是使用 bbox 中的數字和字體大小,您可以很好地自定義它。

import matplotlib.pyplot as plt 
import numpy as np

x = np.arange(0.0, 1, 0.01)
x1 = np.sin(2*np.pi*x)
x2 = np.sin(2*np.pi*x+1)
x3 = np.sin(2*np.pi*x+2)


fig, ax = plt.subplots()
f1, = ax.plot(x1, 'r', lw=4)
f2, = ax.plot(x2, 'k', lw=2)
f3, = ax.plot(x3, 'b', lw=2)

legend1 = plt.legend([f1], ["Main legend"], fontsize=12, loc=3, bbox_to_anchor=(0,0.1,0,0), frameon=False)
legend2 = plt.legend((f2, f3), ('sublegend 1', 'sublegend 2'), fontsize=9,
                 loc=3, bbox_to_anchor=(0.05,0,0,0), frameon=False)
plt.gca().add_artist(legend1)
plt.show()

在此處輸入圖像描述

編輯:

好吧,如果我們插入 2 個圖例,為什么不在更大的圖中插入一個全新的圖形作為插圖,專用於一個圖例,在其中你可以畫和寫任何你喜歡的東西? 誠然,這是一項艱巨的工作,您必須設計內部的每一條線,包括精確的位置坐標。 但這就是我能想到的做你想做的事的方式:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0.0, 1, 0.01)
x1 = np.sin(2*np.pi*x)
x2 = np.sin(2*np.pi*x+1)
x3 = np.sin(2*np.pi*x+2)


fig, ax = plt.subplots()
f1, = ax.plot(x1, 'r', lw=4)
f2, = ax.plot(x2, 'k', lw=2)
f3, = ax.plot(x3, 'b', lw=2)

## set all lines for inner figure
yline1 = np.array([-0.15, -0.15]) 
line1 = np.array([2, 10])
yline2 = np.array([3, 0])
line2 = np.array([4, 4])
yline3 = np.array([1.5, 1.5])
line3 = np.array([4, 6])
yline4 = np.array([1.5, 1.5])
line4 = np.array([7, 10])
yline5 = np.array([3, 3])
line5 = np.array([4, 6])
yline6 = np.array([3, 3])
line6 = np.array([7, 10])

## inset figure
axin1 = ax.inset_axes([2.5, -1, 30, 0.5], transform=ax.transData)  # 

## plot all lines
axin1.plot(line1, yline1, linewidth=4, c='r')
axin1.plot(line2, yline2, 'k', lw=1)
axin1.plot(line3, yline3, 'k', lw=1)
axin1.plot(line4, yline4, 'b', lw=3)
axin1.plot(line5, yline5, 'k', lw=1)
axin1.plot(line6, yline6, 'k', lw=3)

## text
axin1.text(12, 0, 'MAIN', fontsize=12)
axin1.text(12, 1.7, 'Subtext 1', fontsize=10)
axin1.text(12, 3.2, 'Subtext 2', fontsize=10)

## adjust
axin1.set_ylim([4, -1])
axin1.set_xlim([0, 27])
axin1.set_xticklabels('')
axin1.set_yticklabels('')

在此處輸入圖像描述

我在圖例中尋找了一個自定義示例,並沒有看到任何降低級別的跡象。 您只需排列圖例中的對象即可。 我以 colors 和標記的形式創建了呈現圖像的層次結構。 官方參考已定制。 這具有消除以特殊方式僅注釋圖例的需要的效果。

import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerLineCollection, HandlerTuple

fig, ax1 = plt.subplots(1, 1, constrained_layout=True)

params = {'legend.fontsize': 16,
          'legend.handlelength': 3}

plt.rcParams.update(params)

x = np.linspace(0, np.pi, 25)
xx = np.linspace(0, 2*np.pi, 25)
xxx = np.linspace(0, 3*np.pi, 25)

p1, = ax1.plot(x, np.sin(x), lw=5, c='r')
p2, = ax1.plot(x, np.sin(xx), 'm-d', c='g')
p3, = ax1.plot(x, np.sin(xxx), 'm-s', c='b')

# Assign two of the handles to the same legend entry by putting them in a tuple
# and using a generic handler map (which would be used for any additional
# tuples of handles like (p1, p2)).
l = ax1.legend([p1, (p1, p2), (p1, p3)], ['Legend entry', 'Contribution 1', 'Contribution 2'], scatterpoints=1,
               numpoints=1, markerscale=1.3, handler_map={tuple: HandlerTuple(ndivide=None, pad=1.0)})

plt.show()

在此處輸入圖像描述

暫無
暫無

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

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