y轴的刻度标签很长。如何在seaborn中截断它们?

时间:2017-03-12 05:29:56

标签: python python-2.7 matplotlib seaborn

我正在密谋"麦当劳的菜单"来自kaggle的数据。我用食物来绘制营养素。但是,y-tick-labels非常长。如何截断它们以使它们适当地适应?

grouped = df.groupby(df["Protein"])
item = grouped["Item"].sum()
item_list = item.sort_index()
item_list = item_list[-20:]
#Sizing the image canvas
plt.figure(figsize=(8,9))
#To plot bargraph
sns.barplot(item_list.index,item_list.values)

The plot that I got

如何纠正它并改善我的情节大小?

1 个答案:

答案 0 :(得分:2)

一个想法可能是让标签中的文字像一个选框一样滚动。

enter image description here

import matplotlib.pyplot as plt
import matplotlib.text
import matplotlib.animation

class Roller():
    def __init__(self):
        self.texts = []

    def append(self, text, **kwargs):
        RollingText.assimilate(text,  **kwargs)
        self.texts.append(text)

    def roll(self, i=0):
        for text in self.texts:
            text.roll()

    def ticklabelroll(self, i=0):
        self.roll()
        ticklabels = [t.get_text() for t in self.texts]
        plt.gca().set_yticklabels(ticklabels)



class RollingText(matplotlib.text.Text):
    n = 10
    p = 0
    def __init__(self, *args, **kwargs):
        self.n = kwargs.pop("n", self.n)
        matplotlib.text.Text(*args, **kwargs)
        self.set_myprops()

    def set_myprops(self, **kwargs):
        self.fulltext = kwargs.get("fulltext", self.get_text())
        self.n = kwargs.get("n", self.n)
        if len(self.fulltext) <=self.n:
            self.showntext = self.fulltext
        else:
            self.showntext = self.fulltext[:self.n]
        self.set_text(self.showntext)

    def roll(self, by=1):
        self.p += by
        self.p = self.p % len(self.fulltext)
        if self.p+self.n <= len(self.fulltext):
            self.showntext = self.fulltext[self.p:self.p+self.n]
        else:
            self.showntext = self.fulltext[self.p:] + " " + \
                        self.fulltext[0:(self.p+self.n) % len(self.fulltext)]          
        self.set_text(self.showntext)

    @classmethod
    def assimilate(cls, instance, **kwargs):
        # call RollingText.assimilate(Text, n=10, ...)
        instance.__class__ = cls 
        instance.set_myprops(**kwargs)

if __name__ == "__main__":
    import pandas as pd
    import seaborn as sns

    fn = r"data\nutrition-facts-for-mcdonald-s-menu\menu.csv"
    df = pd.read_csv(fn)

    grouped = df.groupby(df["Protein"])
    item = grouped["Item"].sum()
    item_list = item.sort_index()
    item_list = item_list[-20:]

    fig, ax = plt.subplots(figsize=(10,7.5))
    plt.subplots_adjust(left=0.3)

    sns.barplot(item_list.index,item_list.values, ax=ax)

    # create a Roller instance
    r = Roller()
    # append all ticklabels to the Roller
    for tl in ax.get_yticklabels():
        r.append(tl, n=25) 

    #animate the ticklabels
    ani = matplotlib.animation.FuncAnimation(fig, r.ticklabelroll, 
                            frames=36, repeat=True, interval=300)
    ani.save(__file__+".gif", writer="imagemagick")
    plt.show()