1

I have a dataframe that I have plotted as a stacked bar chart and added a table of values below the plot using table=true. I've had to modify it slightly so its readable.

myplot=df.plot.bar(stacked=True,title=name,grid=True,fontsize = 12, table=True)
myplot.axes.get_xaxis().set_visible(False)
table = myplot.tables[0]
# Setting the font size
table.set_fontsize(10)

Output of Current Code

Is it possible to:

  1. Add another row to the table with the SUM values of each column
  2. Remove NaNs
  3. Add background color to the table

Thanks

1 Answer 1

1

Most of this information comes from digging around here:

  1. Table: https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.table.html
  2. Cell: https://matplotlib.org/3.1.1/api/table_api.html#matplotlib.table.Cell
  3. Text: https://matplotlib.org/3.1.1/api/text_api.html#matplotlib.text.Text

I used the strategies recommended here: Matplotlib table formatting

For a complete solution, here is my setup (slight extension of yours):

import pandas as pd
import matplotlib.pyplot as plt

data = {
    1: {'A': 50, 'B': 100, 'C': 55, 'D': 42, 'E': 55},
    2: {'A': 100, 'B': 50, 'C': None, 'D': None, 'E': None},
    3: {'A': 67, 'B': None, 'C': None, 'D': None, 'E': None},
    4: {'A': 50, 'B': None, 'C': None, 'D': None, 'E': None}
}
df = pd.DataFrame(data)
#df = df.swapaxes("index", "columns")

myplot=df.plot.bar(stacked=True,grid=True,fontsize = 12, table=True)
myplot.axes.get_xaxis().set_visible(False)
table = myplot.tables[0]
# Setting the font size
table.set_fontsize(10)

This section iterates through cells in the table, checks if the text is "nan", sets to blank if it is, and sets the color:

# iterate through cells
desiredBgColor = (0.5,0.5,0.5)
tableRowLength = len(df.columns)
tableColLength = len(df.index)
for cIx in range(1, tableColLength): # start with 1 to not include column headers
    for rIx in range(0, tableRowLength + 1): # start with 0 because apparently row index does appear in celldata
        c = table.get_celld()[(cIx, rIx)]
        cellText = c.get_text()
        if (cellText.get_text() == 'nan'):
            cellText.set_text('')
        c.set_color(desiredBgColor)

This adds a sum row:

# add a row
desiredSumRowColor = (.6, .6, .6)
cellWidth = table.get_celld()[(1, 1)].get_width() # have to check width from an existing cell
cellHeight = table.get_celld()[(1, 1)].get_height() # have to check height from an existing cell
for cIx in range(0, tableColLength):
    c = table.add_cell(tableRowLength + 1, cIx, cellWidth, cellHeight)
    c.set_color(desiredSumRowColor)
    c.set
    c.get_text().set_text(df.iloc[cIx].sum())

Final result below:

Plot Image

Sign up to request clarification or add additional context in comments.

3 Comments

This is fantastic, thanks. Is it possible to get the grid lines back or is that asking too much?
@user11305439 c.set_edgecolor('black') will change the grid lines to black on a cell :)
Glad to help! If this solved your issue, could you accept the answer? (Green checkbox). Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.