Creating Tables in Matplotlib

Tables are an excellent way to present tabular data alongside graphs in Matplotlib. This tutorial will guide you through various methods to create and customize tables using the `matplotlib` library.

### Basic Table in Matplotlib

Let's start by creating a simple table and adding it to a plot:

import matplotlib.pyplot as plt
import numpy as np

# Sample data
columns = ('A', 'B', 'C', 'D')
rows = ['Row1', 'Row2', 'Row3']
data = [[123, 211, 232, 121],
        [231, 321, 323, 131],
        [111, 223, 338, 201]]

fig, ax = plt.subplots()

# Hide axes
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
ax.set_frame_on(False)

# Create the table
table = plt.table(cellText=data, colLabels=columns, rowLabels=rows, loc='center')

# Auto scale the table layout
table.scale(1, 1.5)
plt.title('Basic Table in Matplotlib')

plt.show()
- **`plt.table`**: This function creates a table. `cellText` is the data in the table, `colLabels` are the column headers, and `rowLabels` are the row headers.
- **`loc='center'`**: Positions the table at the center of the plot.
- **`table.scale(1, 1.5)`**: Scales the table to fit the plot better.

### Customizing Table Appearance

You can customize the appearance of the table, such as the colors and font sizes.

import matplotlib.pyplot as plt

# Sample data
columns = ('A', 'B', 'C', 'D')
rows = ['Row1', 'Row2', 'Row3']
data = [[123, 211, 232, 121],
        [231, 321, 323, 131],
        [111, 223, 338, 201]]

fig, ax = plt.subplots()

# Hide axes
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
ax.set_frame_on(False)

# Create the table
table = plt.table(cellText=data, colLabels=columns, rowLabels=rows, loc='center', cellLoc='center')

# Customizations
table.auto_set_font_size(False)
table.set_fontsize(12)
table.scale(1.2, 1.2)

# Coloring cells
cell_dict = table.get_celld()
for i in range(len(data) + 1):
    for j in range(len(columns)):
        if i == 0:  # Header cell
            cell_dict[(i, j)].set_facecolor('#40466e')
            cell_dict[(i, j)].set_text_props(color='w')
        else:
            cell_dict[(i, j)].set_facecolor('#f2f4f7')

plt.title('Custom Table Appearance')

plt.show()
- **`cellLoc='center'`**: Centers the text within each cell.
- **`table.auto_set_font_size(False)`**: Disables the automatic font size adjustment.
- **`table.set_fontsize(12)`**: Sets the font size of the table text.
- **`table.get_celld()`**: Gets a dictionary of cells. You can then iterate through this dictionary to customize individual cells.
- **`set_facecolor`** and **`set_text_props`**: Customize the background color and text properties of each cell.

### Advanced Table with Highlighted Cells

For more advanced use cases, you can highlight certain cells based on some criteria.

import matplotlib.pyplot as plt
import numpy as np

# Sample data
columns = ('A', 'B', 'C', 'D')
rows = ['Row1', 'Row2', 'Row3']
data = [[123, 211, 232, 121],
        [231, 321, 323, 131],
        [111, 223, 338, 201]]

fig, ax = plt.subplots()

# Hide axes
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
ax.set_frame_on(False)

# Create the table
table = plt.table(cellText=data, colLabels=columns, rowLabels=rows, loc='center')

# Customizations
for (i, j), cell in table.get_celld().items():
    cell.set_fontsize(12)
    if i == 0 or j == -1:
        cell.set_text_props(weight='bold', color='white')
        cell.set_facecolor('#40466e')
    else:
        if data[i-1][j] > 200:
            cell.set_facecolor('#ff9999')
        else:
            cell.set_facecolor('#99ff99')

table.scale(1.2, 1.2)

plt.title('Advanced Table with Highlighted Cells')

plt.show()
- **`cell.set_text_props(weight='bold', color='white')`** bolds the text and changes its color.
- **`cell.set_facecolor('#ff9999')`** and **`cell.set_facecolor('#99ff99')`** set the cell background color based on a condition.

### Table with Data Plot

Integrating a table with a data plot can provide a comprehensive view of the data.

import numpy as np 
import matplotlib.pyplot as plt 
  
# Energy consumption data for 4 quarters: Electricity and Gas consumption (in kWh)
consumption_data = [
    [250, 300, 320, 280],  # Electricity consumption
    [210, 110, 80, 180]   # Gas consumption
]

quarters = ['Q1', 'Q2', 'Q3', 'Q4']
rows = ['Electricity', 'Gas']
columns = quarters
colors = plt.get_cmap('tab10').colors

cell_text = []
for row in range(len(consumption_data)):
    plt.plot(columns, consumption_data[row], color=colors[row], label=rows[row])
    cell_text.append([x for x in consumption_data[row]])

table = plt.table(cellText=cell_text,
                      rowLabels=rows,
                      rowColours=colors,
                      colLabels=columns,
                      loc='bottom')

plt.ylabel("Energy Consumption (kWh)")
plt.xticks([])
plt.title('Monthly Energy Consumption Over 5 Years')
plt.show()
- `plt.plot(columns, consumption_data[row], color=colors[row], label=rows[row])` plots the data for each row (Electricity and Gas) as a line plot with different colors.
- `loc='bottom'` positions the table at the bottom of the plot.
- `plt.xticks([])` removes the x-axis ticks for a cleaner plot


### Conclusion

Creating and customizing tables in Matplotlib allows you to present tabular data effectively alongside your plots. With various options to adjust the appearance, colors, and fonts, you can make your tables informative and visually appealing.