【问题标题】:How to manually create a legend如何手动创建图例
【发布时间】:2022-03-24 16:53:58
【问题描述】:

我正在使用 matlibplot,我想手动将项目添加到图例中,这些项目是颜色和标签。我正在向图中添加数据以指定会导致大量重复。

我的想法是:

    ax2.legend(self.labels,colorList[:len(self.labels)])
    plt.legend()

其中 self.labels 是我想要的图例标签的项目数,它采用大型颜色列表的子集。但是,当我运行它时,这不会产生任何结果。

我错过了什么吗?

谢谢

【问题讨论】:

标签: python matplotlib seaborn legend


【解决方案1】:

你检查过Legend Guide吗?

为了实用,我引用guide的例子。

并非所有句柄都可以自动变成图例条目,所以它 通常需要创造一个可以的艺术家。图例手柄不 必须存在于图形或轴上才能使用。

假设我们想创建一个图例,其中包含一些数据的条目 用红色表示:

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

red_patch = mpatches.Patch(color='red', label='The red data')
plt.legend(handles=[red_patch])

plt.show()

编辑

要添加两个补丁,您可以这样做:

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

red_patch = mpatches.Patch(color='red', label='The red data')
blue_patch = mpatches.Patch(color='blue', label='The blue data')

plt.legend(handles=[red_patch, blue_patch])

【讨论】:

  • 如何添加多个?我可以列出补丁列表,然后执行 plt.legend(handles=patchList)
  • @Bradyforcier 完全正确。
  • 我尝试像这样添加我的自定义补丁,我在图例中看到两个黑点和补丁'>。我尝试在上面添加 red_pa​​tch,我得到了同样的结果。补丁被添加为 plt.legend(mpatches.Patch(color='red', label='The red data'))。原来我坚持使用的版本是超级旧的 0.99。不知道如何了解这个旧 API 的工作原理
  • @Bradyforcier 我添加了一个带有两个补丁的示例。我不确定它是否适用于 v0.99。
  • 是否也可以手动将一种颜色分配给一个特定值?
【解决方案2】:

对于那些想要将手动图例项添加到具有自动生成项的单个/常见图例中的人:

#Imports
import matplotlib.patches as mpatches

# where some data has already been plotted to ax
handles, labels = ax.get_legend_handles_labels()

# manually define a new patch 
patch = mpatches.Patch(color='grey', label='Manual Label')

# handles is a list, so append manual patch
handles.append(patch) 

# plot the legend
plt.legend(handles=handles, loc='upper center')

手动和自动生成项目的常见图例示例:

已添加 2021-05-23

带有手动线和补丁的完整示例

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
import matplotlib.patches as mpatches

plt.plot([1,2,3,4], [10,20,30,40], label='My Data', color='red')

handles, labels = plt.gca().get_legend_handles_labels()

patch = mpatches.Patch(color='grey', label='manual patch')   
line = Line2D([0], [0], label='manual line', color='k')

handles.extend([patch,line])

plt.legend(handles=handles)
plt.show()

【讨论】:

  • 对于使用标准 matplotlib.pyplot 作为 plt 的任何人,我必须这样做:plt.legend()handles, labels = plt.gca().get_legend_handles_labels()
  • 一个更好的答案,因为它显示附加到生成的标签,而不是手动添加所有内容。
  • 如果我想让标签看起来像一条黑线而不是黑块怎么办?我尝试更改linewidth,但它只会更改块周围的框架。
  • @Shaun Han ...请参阅我的答案所附的块
【解决方案3】:

这是一个解决方案,可让您控制图例线的宽度和样式(在a lot of other things 中)。

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

colors = ['black', 'red', 'green']
lines = [Line2D([0], [0], color=c, linewidth=3, linestyle='--') for c in colors]
labels = ['black data', 'red data', 'green data']
plt.legend(lines, labels)
plt.show()

更多选项,请查看matplotlib gallery sample

【讨论】:

    【解决方案4】:

    我正在添加一些代码来构建来自https://stackoverflow.com/users/2029132/gabra 的答案和来自https://stackoverflow.com/users/5946578/brady-forcier 的评论。在这里,我手动将元素添加到图例中通过'for'循环。

    首先,我创建一个包含我的图例名称和所需颜色的字典。我实际上是在加载数据时这样做的,但在这里我只是明确定义:

    import matplotlib.patches as mpatches
    import matplotlib.pyplot as plt    
    
    legend_dict = { 'data1' : 'green', 'data2' : 'red', 'data3' : 'blue' }
    

    然后我遍历字典并为每个条目定义一个补丁并附加到一个列表'patchList'。然后我使用这个列表来创建我的图例。

    patchList = []
    for key in legend_dict:
            data_key = mpatches.Patch(color=legend_dict[key], label=key)
            patchList.append(data_key)
    
    plt.legend(handles=patchList)
    plt.savefig('legend.png', bbox_inches='tight')
    

    这是我的输出:

    我不担心图例条目按特定顺序排列,但您可以通过

    实现这一点
    plt.legend(handles=sorted(patchList))
    

    这是我的第一个答案,如有任何错误/失礼,请提前道歉。

    【讨论】:

    • 我可以用圆形补丁代替矩形吗?
    • @seralouk 你可能想看看这个
    【解决方案5】:

    我最后写了这个:

    def plot_bargraph_with_groupings(df, groupby, colourby, title, xlabel, ylabel):
        """
        Plots a dataframe showing the frequency of datapoints grouped by one column and coloured by another.
        df : dataframe
        groupby: the column to groupby
        colourby: the column to color by
        title: the graph title
        xlabel: the x label,
        ylabel: the y label
        """
    
        import matplotlib.patches as mpatches
    
        # Makes a mapping from the unique colourby column items to a random color.
        ind_col_map = {x:y for x, y in zip(df[colourby].unique(),
                                   [plt.cm.Paired(np.arange(len(df[colourby].unique())))][0])}
    
    
        # Find when the indicies of the soon to be bar graphs colors.
        unique_comb = df[[groupby, colourby]].drop_duplicates()
        name_ind_map = {x:y for x, y in zip(unique_comb[groupby], unique_comb[colourby])}
        c = df[groupby].value_counts().index.map(lambda x: ind_col_map[name_ind_map[x]])
    
        # Makes the bargraph.
        ax = df[groupby].value_counts().plot(kind='bar',
                                             figsize=FIG_SIZE,
                                             title=title,
                                             color=[c.values])
        # Makes a legend using the ind_col_map
        legend_list = []
        for key in ind_col_map.keys():
            legend_list.append(mpatches.Patch(color=ind_col_map[key], label=key))
    
        # display the graph.
        plt.legend(handles=legend_list)
        ax.set_xlabel(xlabel)
        ax.set_ylabel(ylabel)
    

    【讨论】:

      【解决方案6】:

      一个简单的方法是在需要时强制使用标签:

      # add the following line after the code that plots your graph
      
      plt.legend(['Name1', 'Name2'])
      

      例子:

      axes[ax] = sns.lineplot(x='days', y='value', data=dataset, palette = 'coolwarm', lw=5)
      axes[ax].set_title('Value Across Days')
      axes[ax].set_xlabel('Days')
      axes[ax].set_ylabel('Value')
      axes[ax].legend(['Measurement1', 'Measurement2'], loc='best')
      

      结果:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多