Search code examples
pythonmatplotlibpie-chart

use textwrap.shorten with a list


this code creates me a table in an excel file and a pie plot, the label fields, taken from a list of values, are way too long.

    plt.pie(df.Confronto.value_counts(),
        labels=textwrap.shorten(df.Confronto.value_counts().index.tolist(), width=10, placeholder="..."))
    plt.title("Confronto {} - {}".format(Mese,Mese2,))
    plt.show()

So I tried to shorten it using text.shorten, but it gives me this error:

labels=textwrap.shorten(df.Confronto.value_counts().index.tolist(), width=10, placeholder="...")) 
AttributeError: 'list' object has no attribute 'strip'

I tried to cast but it gave me an error about the indeterminate length of the label

labels=textwrap.shorten(str(df.Confronto.value_counts().index.tolist()), width=10, placeholder="...")

raise ValueError("'label' must be of length 'x'")
ValueError: 'label' must be of length 'x'

The image below shows the result of the code in its current state: the labels are too long and at the time the image is created nothing is read, I wish I could put a maximum on the length of the labels.

Image


Solution

  • I am not sure as to what you are trying to achieve with this code, so I'll just explain why the exception is raised. That happens because pandas.Index.tolist returns a list, and textwrap.shorten is used on strings. So, cannot strip a string if it's a list.

    I assume df.Confronto.value_counts().index.tolist() returns a list of int, like [1,2,3]. You may try joining the list first with

    label_string = ''.join(map(str,[1,2,3]))
    Out: '123'
    

    It first maps str() over your list of int to produce a list of str, then joins the list in a single string with a '' symbol.

    However, labels= takes the list of str, so you might want to restore it back to list with

    label_list = [ch for ch in label_string]
    

    or even slice the original df.Confronto.value_counts().index.tolist() to reduce the number of elements, and then map str() over it.

    After clarification in comments I suggest a list comprehension to iterate textwrap on given list:

    label_list = [textwrap.shorten(string, width=10, placeholder="...") for string in df.Confronto.value_counts().index.tolist()]