Seaborn countplot 为 x 值设置图例

Che*_*eng 5 python matplotlib seaborn

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

我正在尝试将 x 值的图例添加到图中,如下所示:句柄是 x 值的集合,标签是 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())
Run Code Online (Sandbox Code Playgroud)

但是,我收到警告说

用户警告:

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

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

在此处输入图片说明

谢谢你的帮助。

Imp*_*est 5

这是一个可能的解决方案,创建一个文本字段作为图例处理程序。下面将创建一个TextHandler用于创建图例艺术家的,这是一个简单的matplotlib.text.Text实例。图例的句柄作为(文本,颜色)的元组给出,从中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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


上面的解决方案是下面原始版本的更新版本,看起来更复杂。以下是原始解决方案,它使用 aTextArea和 anAnchoredOffsetbox将文本放置在图例中。

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()
Run Code Online (Sandbox Code Playgroud)

另请参阅此更通用的答案