【问题标题】:Python: Making one legend that spans two subplotsPython:制作一个跨越两个子图的图例
【发布时间】:2016-07-15 17:46:23
【问题描述】:

我正在寻找的基本设计是我有两个并排的散点图,然后我想在两个子图下方创建一个图例,跨越它们。这是一个粗略的草图:

我能够使情节没有问题,但我很难让传奇人物做我想做的事。这是我制作两个散点图的代码示例(我有比这更多的数据点,但为了空间,我只包括一些):

import numpy as np
from numpy import array
import matplotlib.pyplot as plt

x = [5,10,20,30]

med1 = [9.35,15.525,26.1,48.275]
med2 = [8.75,14.025,23.95,41.025] 

iqr1 = [13.5125,19.95,38.175,69.9] 
iqr2 = [12.05,19.075,35.075,62.875]

plt.subplot(121)
plt.scatter(x, med1, color='red', alpha=0.5, label='Red stuff')
plt.scatter(x, med2, color='blue', alpha=0.5, label='Blue stuff')
plt.xlim([0,35])
plt.ylim([0,75])
plt.xlabel('Channel Area')
plt.ylabel('Median')

plt.subplot(122)
plt.scatter(x, iqr1, color='red', alpha=0.5, label='More Red Stuff')
plt.scatter(x, iqr2, color='blue', alpha=0.5, label = 'More Blue Stuff')
plt.xlim([0,35])
plt.ylim([0,75])
plt.xlabel('Channel Area')
plt.ylabel('IQR')

使图例如上图所示的最佳方式是什么?

【问题讨论】:

    标签: python matplotlib subplot


    【解决方案1】:

    你想使用figlegend (demo)

    figlegend( (line1, line2, line3), ('label1', 'label2', 'label3'), 'upper right' )
    

    也看看这个问题的答案 How to position and align a matplotlib figure legend?

    【讨论】:

      【解决方案2】:

      matplotlib - Legend with multiple axes with errorbar objectHow to put the legend out of the plot 借用代码,您可以使用这些命令来做到这一点:

      #获取lengend句柄和标签 h1, l1 = ax1.get_legend_handles_labels() h2, l2 = ax2.get_legend_handles_labels()

      #Shrink the subplots to make room for the legend
      box = ax1.get_position()
      ax1.set_position([box.x0, box.y0 + box.height * 0.1,
                       box.width, box.height * 0.9])
      box = ax2.get_position()
      ax2.set_position([box.x0, box.y0 + box.height * 0.1,
                       box.width, box.height * 0.9])
      #Make the legend
      ax1.legend(h1+h2, l1+l2,  bbox_to_anchor=(0,-.05, 2.2,-0.15), loc=9,
                 ncol=4)
      

      其中 ax1 和 ax2 是子图的轴

      在您的示例中,您可以这样实现:

      import matplotlib.pyplot as plt
      plt.style.use('ggplot')
      
      x = [5,10,20,30]
      
      med1 = [9.35,15.525,26.1,48.275]
      med2 = [8.75,14.025,23.95,41.025] 
      
      iqr1 = [13.5125,19.95,38.175,69.9] 
      iqr2 = [12.05,19.075,35.075,62.875]
      
      ax1 = plt.subplot(121)
      plt.scatter(x, med1, marker='^',color='black', alpha=0.5, label='Triangle!')
      plt.scatter(x, med2, color='blue', alpha=0.5, label='Blue Dot')
      plt.xlim([0,35])
      plt.ylim([0,75])
      plt.xlabel('Channel Area')
      plt.ylabel('Median')
      # ax1 = plt.gca()
      
      ax2 = plt.subplot(122)
      plt.scatter(x, iqr1, color='red', alpha=0.5, label='Red Dot')
      plt.scatter(x, iqr2, marker='D',color='blue', alpha=0.5, label = 'Diamonds')
      plt.xlim([0,35])
      plt.ylim([0,75])
      plt.xlabel('Channel Area')
      plt.ylabel('IQR')
      # ax2=plt.gca()
      
      plt.tight_layout() # No overlap of subplots
      
      #Get the lengend handles and labels
      h1, l1 = ax1.get_legend_handles_labels()
      h2, l2 = ax2.get_legend_handles_labels()
      
      #Shrink the subplots to make room for the legend
      box = ax1.get_position()
      ax1.set_position([box.x0, box.y0 + box.height * 0.1,
                       box.width, box.height * 0.9])
      box = ax2.get_position()
      ax2.set_position([box.x0, box.y0 + box.height * 0.1,
                       box.width, box.height * 0.9])
      #Make the legend
      ax1.legend(h1+h2, l1+l2,  bbox_to_anchor=(0,-.05, 2.2,-0.15), loc=9,
                 ncol=4)
      plt.show()
      

      您可以使用bboxncolmode="expand"borderaxespad=0。有关更多信息,请参阅http://matplotlib.org/users/legend_guide.html#legend-location。上面的代码应该会产生这个情节:

      【讨论】:

      • 这看起来真不错!出于学习目的,您能告诉我这部分代码对 ax1.legen 的作用:h1+h2、l1+l2、bbox_to_anchor=(0,-.05, 2.2,-0.15) 和 loc=9?我不确定这些对传说有什么影响,所以我很好奇他们做了什么
      猜你喜欢
      • 1970-01-01
      • 2017-04-17
      • 2022-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-26
      • 1970-01-01
      相关资源
      最近更新 更多