【问题标题】:Seaborn countplot set legend for x valuesSeaborn countplot 为 x 值设置图例
【发布时间】:2017-04-24 10:10:40
【问题描述】:

我正在通过sns.countplot() 绘制分类数据和值计数

我正在尝试在图中添加 x 值的图例,如下所示:handles 是 x 值的集合,labels 是 x 值的描述。

ax = sns.countplot(x = df.GARAGE_DOM)
handles, labels = ax.get_legend_handles_labels()

handles = ["VP", "BC", "GC", "GP", "JC", "PO"]
labels = ["Voie Publique", "box", "Garage couvert", "garage particulier clos", "Jardin clos", "parking ouvert"]
by_label = OrderedDict(zip(handles,labels))
ax.legend(by_label.keys(), by_label.values())

但是,我收到了警告

用户警告:

Legend 不支持“VP”实例。 可以使用代理艺术家代替。 见:http://matplotlib.org/users/legend_guide.html#using-proxy-artist

我已阅读代理艺术家的文档,但在我的案例中没有找到示例。

感谢您的帮助。

【问题讨论】:

    标签: python matplotlib seaborn


    【解决方案1】:

    这是一个可能的解决方案,创建一个文本字段作为图例处理程序。 下面将创建一个TextHandler 用于创建图例艺术家,这是一个简单的matplotlib.text.Text 实例。图例的句柄以 (text, color) 的元组形式给出,TextHandler 从中创建所需的 Text

    import seaborn as sns
    import matplotlib.pyplot as plt
    from matplotlib.legend_handler import HandlerBase
    from matplotlib.text import Text
    import numpy as np
    import pandas as pd
    
    class TextHandler(HandlerBase):
        def create_artists(self, legend, tup ,xdescent, ydescent,
                            width, height, fontsize,trans):
            tx = Text(width/2.,height/2,tup[0], fontsize=fontsize,
                      ha="center", va="center", color=tup[1], fontweight="bold")
            return [tx]
    
    
    a = np.random.choice(["VP", "BC", "GC", "GP", "JC", "PO"], size=100, 
                         p=np.arange(1,7)/21. )
    df = pd.DataFrame(a, columns=["GARAGE_DOM"])
    
    ax = sns.countplot(x = df.GARAGE_DOM)
    
    
    handltext = ["VP", "BC", "GC", "GP", "JC", "PO"]
    labels = ["Voie Publique", "box", "Garage couvert", "garage particulier clos", "Jardin clos", "parking ouvert"]
    
    
    t = ax.get_xticklabels()
    labeldic = dict(zip(handltext, labels))
    labels = [labeldic[h.get_text()]  for h in t]
    handles = [(h.get_text(),c.get_fc()) for h,c in zip(t,ax.patches)]
    
    ax.legend(handles, labels, handler_map={tuple : TextHandler()}) 
    
    plt.show()
    


    上面的解决方案是下面原版本的更新版本,看起来比较复杂。 以下是原始解决方案,它使用TextAreaAnchoredOffsetbox 将文本放置在图例中。
    import seaborn.apionly as sns
    import matplotlib.pyplot as plt
    import matplotlib.patches as patches
    from matplotlib.offsetbox import TextArea, AnchoredOffsetbox
    from matplotlib.transforms import TransformedBbox, Bbox
    from matplotlib.legend_handler import HandlerBase
    import numpy as np
    import pandas as pd
    
    class TextHandler(HandlerBase):
        def __init__(self, text, color="k"):
            self.text = text 
            self.color = color
            super(TextHandler, self).__init__()
    
        def create_artists(self, legend, orig_handle,xdescent, ydescent,
                            width, height, fontsize,trans):
            bb = Bbox.from_bounds(xdescent,ydescent, width,height)
            tbb = TransformedBbox(bb, trans)
            textbox = TextArea(self.text, textprops={"weight":"bold","color":self.color})
            ab = AnchoredOffsetbox(loc=10,child=textbox, bbox_to_anchor=tbb, frameon=False)
            return [ab]
    
    
    a = np.random.choice(["VP", "BC", "GC", "GP", "JC", "PO"], size=100, 
                         p=np.arange(1,7)/21. )
    df = pd.DataFrame(a, columns=["GARAGE_DOM"])
    
    ax = sns.countplot(x = df.GARAGE_DOM)
    
    
    handltext = ["VP", "BC", "GC", "GP", "JC", "PO"]
    labels = ["Voie Publique", "box", "Garage couvert", "garage particulier clos", "Jardin clos", "parking ouvert"]
    
    handles = [ patches.Rectangle((0,0),1,1) for h in handltext]
    t = ax.get_xticklabels()
    labeldic = dict(zip(handltext, labels))
    labels = [labeldic[h.get_text()]  for h in t]
    handlers = [TextHandler(h.get_text(),c.get_fc()) for h,c in zip(t,ax.patches)]
    handlermap = dict(zip(handles, handlers))
    ax.legend(handles, labels, handler_map=handlermap,) 
    
    plt.show()
    

    另见this more generic answer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-30
      • 2017-07-22
      • 2023-01-23
      • 2021-04-08
      • 2017-09-24
      • 1970-01-01
      • 1970-01-01
      • 2018-06-11
      相关资源
      最近更新 更多