Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Data Science Basics Creating Reports Saving PDFs

Liat Hoffman
Liat Hoffman
9,316 Points

This is not working on my local instance of python - please help.

Here is my code:

from s6v1 import *
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages


def plot_minimal_graph(tally, columns, *args):
    plt.style.use("bmh")
    fig = plt.figure(dpi = 200)
    colors = plt.rcParams['axes.color_cycle']

    #-- white background to use less printer ink---#

    ax = plt.subplot(111, axisbg = 'white')

    # Plot bars and create text labels for the table

    for priceBucket in tally:
        ax.bar(priceBucket, tally[priceBucket], color = colors[priceBucket%len(tally)])
        ax.annotate(r"%d" % (tally[priceBucket]),
                    (priceBucket+0.2, tally[priceBucket]),
                    va = "bottom", ha="center")

    # Include a legend

    ax.legend(columns)

    # Remove distrating lines on top, left and right

    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['left'].set_visible(False)

    # Remove distracting tick marks

    ax.yaxis.set_ticks_position('none')
    ax.xaxis.set_ticks_position('none')

    # Add chart titel and axes labels
    plt.xlabel("Tie Price", fontsize = 13)
    plt.ylabel("Number of Ties", fontsize = 13)
    plt.title("Chart #1")

    #Add labels to bars along x axes
    x = range(1, len(tally) + 1)
    plt.xticks(x, columns, rotation = "horizontal", ha = "left")

    return fig

def plot_graph_with_table(cell_text, row_text, columns):
        plt.style.use("ggplot")
        fig = plt.figure()

        # Include table

        ax2 = fig.add_subplot(111)
        ax2.axis("off")

        the_table = ax2.table(cellText= cell_text,
                                rowLabels = row_text,
                                colLabels = columns,
                                loc = 'center right')

pp = PdfPages("my_report.pdf")

plot1 = plot_minimal_graph(price_groups, columns)
pp.savefig(plot1, bbox_inches = 'tight')

table_text = build_table_text(brand_and_price_data, brands)
plot2 = plot_graph_with_table(table_text[0], table_text[1], columns)
pp.savefig(plot2, bbox_inches = 'tight')

pp.close()

when I run it, I get the following exception:

Traceback (most recent call last):
  File ".\s6v2.py", line 69, in <module>
    plot2 = plot_graph_with_table(table_text[0], table_text[1], columns)
  File ".\s6v2.py", line 61, in plot_graph_with_table
    loc = 'center right')
  File "C:\...\Continuum\Anaconda3\lib\site-packages\matplotlib\axes\_axes.py", line 5372, in table
    return mtable.table(self, **kwargs)
  File "C:\...\Continuum\Anaconda3\lib\site-packages\matplotlib\table.py", line 483, in table
    cols = len(cellText[0])
IndexError: list index out of range

any advice? Thanks!

[MOD: added ```python and ```bash formatting around the code blocks -cf]

Chris Freeman
Chris Freeman
Treehouse Moderator 68,423 Points

I don't see an obvious error. The "index out of range" on a len() statement suggests that the data is missing or None. I suggest using print to inspect table_text[0], table_text[1], and columns.

Liat Hoffman
Liat Hoffman
9,316 Points

Hi Chris Thanks for your advice. Here is the result:

>>> print(table_text[0], table_text[1], columns)
[] [] ['$0-50', '$50-100', '$100-150', '$150-200', '$200-250', '$250+']

followed by the same "IndexError: list index out of range" exception.

I'm thinking this is yet another drawback to running python on Windows. It is frustrating.

[MOD: added ```bash formatting -cf]

Chris Freeman
Chris Freeman
Treehouse Moderator 68,423 Points

That's progress. Now we just need to figure out why text_table[0] is empty [ ].

3 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,423 Points

Rewatching the styling video, at 2:28, Kat seems to have the exact same error. She comments out a line, in s5v3.py.

# s5v3.py
# create_table(brand_and_price_data, price_groups, brands, columns, "_charts/s5_prices_in_table.png")
Liat Hoffman
Liat Hoffman
9,316 Points

Hi Chris Thanks for your help. I went back to s5v3.py and commented out the line you indicated, then ran "python s6v2.py"

the exception is the same:

Traceback (most recent call last): File "s6v2.py", line 69, in <module> plot2 = plot_graph_with_table(table_text[0], table_text[1], columns) File "s6v2.py", line 61, in plot_graph_with_table loc = 'center right') File "C:\Users\-----\AppData\Local\Continuum\Anaconda3\lib\site-packages\matplotlib\axes\_axes.py", line 5372, in t able return mtable.table(self, **kwargs) File "C:\Users\-----\AppData\Local\Continuum\Anaconda3\lib\site-packages\matplotlib\table.py", line 483, in table cols = len(cellText[0]) IndexError: list index out of range

going to try your first suggestion now.

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,423 Points

I think something in the creation of table_text using build_table_text is at issue. When I run your code I get a PDF. When I run it interactively, I get values for table_text. (note: I added extra empty comment lines to run in interactive shell with cut-and-paste)

$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from s6v1 import *
/home/chrisf/.virtualenvs/data_science/lib/python3.4/site-packages/matplotlib/__init__.py:892: UserWarning: axes.color_cycle is deprecated and replaced with axes.prop_cycle; please use the latter.
  warnings.warn(self.msg_depr % (key, alt_key))
>>> import matplotlib.pyplot as plt
>>> from matplotlib.backends.backend_pdf import PdfPages
>>> 
>>> def plot_minimal_graph(tally, columns, *args):
...     plt.style.use("bmh")
...     fig = plt.figure(dpi = 200)
...     colors = plt.rcParams['axes.color_cycle']
...     #
...     #-- white background to use less printer ink---#
...     #
...     ax = plt.subplot(111, axisbg = 'white')
...     #
...     # Plot bars and create text labels for the table
...     #
...     for priceBucket in tally:
...         ax.bar(priceBucket, tally[priceBucket], color = colors[priceBucket % len(tally)])
...         ax.annotate(r"%d" % (tally[priceBucket]),
...                     (priceBucket+0.2, tally[priceBucket]),
...                     va = "bottom", ha="center")
...     #
...     # Include a legend
...     #
...     ax.legend(columns)
...     #
...     # Remove distrating lines on top, left and right
...     #
...     ax.spines['top'].set_visible(False)
...     ax.spines['right'].set_visible(False)
...     ax.spines['left'].set_visible(False)
...     #
...     # Remove distracting tick marks
...     #
...     ax.yaxis.set_ticks_position('none')
...     ax.xaxis.set_ticks_position('none')
...     #
...     # Add chart titel and axes labels
...     plt.xlabel("Tie Price", fontsize = 13)
...     plt.ylabel("Number of Ties", fontsize = 13)
...     plt.title("Chart #1")
...     #
...     #Add labels to bars along x axes
...     x = range(1, len(tally) + 1)
...     plt.xticks(x, columns, rotation = "horizontal", ha = "left")
...     #
...     return fig
... 
>>> def plot_graph_with_table(cell_text, row_text, columns):
...         plt.style.use("ggplot")
...         fig = plt.figure()
...         #
...         # Include table
...         #
...         ax2 = fig.add_subplot(111)
...         ax2.axis("off")
...         #
...         the_table = ax2.table(cellText= cell_text,
...                                 rowLabels = row_text,
...                                 colLabels = columns,
...                                 loc = 'center right')
... 
>>> pp = PdfPages("my_report.pdf")
>>> plot1 = plot_minimal_graph(price_groups, columns)
>>> pp.savefig(plot1, bbox_inches = 'tight')
>>> table_text = build_table_text(brand_and_price_data, brands)
>>> table_text
([[113, 140, 78, 69, 43, 26], [2, 34, 10, 0, 0, 0], [2, 9, 24, 59, 1, 3], [1, 3, 2, 78, 0, 0], [1, 8, 0, 0, 0, 0], [1, 5, 4, 0, 0, 2], [4, 5, 0, 0, 0, 0], [1, 5, 1, 0, 0, 0], [1, 1, 9, 41, 52, 14], [1, 10, 0, 0, 0, 0], [1, 15, 11, 0, 0, 0], [1, 15, 0, 0, 0, 0], [6, 22, 7, 36, 0, 4], [1, 91, 0, 0, 0, 0], [1, 4, 0, 0, 0, 0], [2, 72, 90, 31, 5, 1], [1, 4, 0, 0, 0, 0], [1, 16, 1, 0, 0, 0], [3, 20, 30, 0, 0, 0], [2, 29, 66, 1, 0, 0], [1, 8, 0, 0, 0, 0], [6, 92, 0, 0, 0, 0], [14, 36, 0, 0, 0, 0], [1, 2, 0, 1, 0, 0], [2, 67, 0, 0, 0, 0], [3, 11, 3, 19, 0, 0]], ['', 'Brooks Brothers', 'Burberry', 'Canali', 'Celine', 'Christian Dior', 'DKNY', 'Diesel', 'Dolce & Gabbana', 'Donald Trump', 'Fendi', 'Geoffrey Beene', 'Gucci', 'J.Crew', 'Jos. A. Bank', 'Lanvin', 'Lauren Ralph Lauren', 'Neiman Marcus', 'Paul Smith', 'Polo Ralph Lauren', 'Prada', 'Ted Baker', 'Tommy Hilfiger', 'Turnbull & Asser', 'Vineyard Vines', 'Yves Saint Laurent'])
>>> table_text[0]
[[113, 140, 78, 69, 43, 26], [2, 34, 10, 0, 0, 0], [2, 9, 24, 59, 1, 3], [1, 3, 2, 78, 0, 0], [1, 8, 0, 0, 0, 0], [1, 5, 4, 0, 0, 2], [4, 5, 0, 0, 0, 0], [1, 5, 1, 0, 0, 0], [1, 1, 9, 41, 52, 14], [1, 10, 0, 0, 0, 0], [1, 15, 11, 0, 0, 0], [1, 15, 0, 0, 0, 0], [6, 22, 7, 36, 0, 4], [1, 91, 0, 0, 0, 0], [1, 4, 0, 0, 0, 0], [2, 72, 90, 31, 5, 1], [1, 4, 0, 0, 0, 0], [1, 16, 1, 0, 0, 0], [3, 20, 30, 0, 0, 0], [2, 29, 66, 1, 0, 0], [1, 8, 0, 0, 0, 0], [6, 92, 0, 0, 0, 0], [14, 36, 0, 0, 0, 0], [1, 2, 0, 1, 0, 0], [2, 67, 0, 0, 0, 0], [3, 11, 3, 19, 0, 0]]
>>> table_text[1]
['', 'Brooks Brothers', 'Burberry', 'Canali', 'Celine', 'Christian Dior', 'DKNY', 'Diesel', 'Dolce & Gabbana', 'Donald Trump', 'Fendi', 'Geoffrey Beene', 'Gucci', 'J.Crew', 'Jos. A. Bank', 'Lanvin', 'Lauren Ralph Lauren', 'Neiman Marcus', 'Paul Smith', 'Polo Ralph Lauren', 'Prada', 'Ted Baker', 'Tommy Hilfiger', 'Turnbull & Asser', 'Vineyard Vines', 'Yves Saint Laurent']
>>> 
Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,423 Points

Since your comment above showing the result:

>>> print(table_text[0], table_text[1], columns)
[] [] ['$0-50', '$50-100', '$100-150', '$150-200', '$200-250', '$250+']

I would suggest walking back through the code looking at where the data is missing.. brand_and_price_data is created in s5v3.py:

brand_and_price_data = open_with_csv("_data/tempTableFile.csv", d=',')

Check if this has real data. Perhaps the CSV file contains bad data.