Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8e6d6b6

Browse files
anijjartimhoffm
andauthored
Feature: Support passing DataFrames to table.table (#28830)
--------- Co-authored-by: Tim Hoffmann <[email protected]>
1 parent 651db62 commit 8e6d6b6

File tree

5 files changed

+71
-3
lines changed

5 files changed

+71
-3
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
``ax.table`` will accept a pandas DataFrame
2+
--------------------------------------------
3+
4+
The `~.axes.Axes.table` method can now accept a Pandas DataFrame for the ``cellText`` argument.
5+
6+
.. code-block:: python
7+
8+
import matplotlib.pyplot as plt
9+
import pandas as pd
10+
11+
data = {
12+
'Letter': ['A', 'B', 'C'],
13+
'Number': [100, 200, 300]
14+
}
15+
16+
df = pd.DataFrame(data)
17+
fig, ax = plt.subplots()
18+
table = ax.table(df, loc='center') # or table = ax.table(cellText=df, loc='center')
19+
ax.axis('off')
20+
plt.show()

lib/matplotlib/cbook.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,3 +2391,15 @@ def _auto_format_str(fmt, value):
23912391
return fmt % (value,)
23922392
except (TypeError, ValueError):
23932393
return fmt.format(value)
2394+
2395+
2396+
def _is_pandas_dataframe(x):
2397+
"""Check if 'x' is a Pandas DataFrame."""
2398+
try:
2399+
# we're intentionally not attempting to import Pandas. If somebody
2400+
# has created a Pandas DataFrame, Pandas should already be in sys.modules
2401+
return isinstance(x, sys.modules['pandas'].DataFrame)
2402+
except Exception: # TypeError, KeyError, AttributeError, maybe others?
2403+
# we're attempting to access attributes on imported modules which
2404+
# may have arbitrary user code, so we deliberately catch all exceptions
2405+
return False

lib/matplotlib/table.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
from .transforms import Bbox
3434
from .path import Path
3535

36+
from .cbook import _is_pandas_dataframe
37+
3638

3739
class Cell(Rectangle):
3840
"""
@@ -670,7 +672,7 @@ def table(ax,
670672
671673
Parameters
672674
----------
673-
cellText : 2D list of str, optional
675+
cellText : 2D list of str or pandas.DataFrame, optional
674676
The texts to place into the table cells.
675677
676678
*Note*: Line breaks in the strings are currently not accounted for and
@@ -740,6 +742,21 @@ def table(ax,
740742
cols = len(cellColours[0])
741743
cellText = [[''] * cols] * rows
742744

745+
# Check if we have a Pandas DataFrame
746+
if _is_pandas_dataframe(cellText):
747+
# if rowLabels/colLabels are empty, use DataFrame entries.
748+
# Otherwise, throw an error.
749+
if rowLabels is None:
750+
rowLabels = cellText.index
751+
else:
752+
raise ValueError("rowLabels cannot be used alongside Pandas DataFrame")
753+
if colLabels is None:
754+
colLabels = cellText.columns
755+
else:
756+
raise ValueError("colLabels cannot be used alongside Pandas DataFrame")
757+
# Update cellText with only values
758+
cellText = cellText.values
759+
743760
rows = len(cellText)
744761
cols = len(cellText[0])
745762
for row in cellText:

lib/matplotlib/table.pyi

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ from .transforms import Bbox
88
from .typing import ColorType
99

1010
from collections.abc import Sequence
11-
from typing import Any, Literal
11+
from typing import Any, Literal, TYPE_CHECKING
12+
13+
from pandas import DataFrame
1214

1315
class Cell(Rectangle):
1416
PAD: float
@@ -68,7 +70,7 @@ class Table(Artist):
6870

6971
def table(
7072
ax: Axes,
71-
cellText: Sequence[Sequence[str]] | None = ...,
73+
cellText: Sequence[Sequence[str]] | DataFrame | None = ...,
7274
cellColours: Sequence[Sequence[ColorType]] | None = ...,
7375
cellLoc: Literal["left", "center", "right"] = ...,
7476
colWidths: Sequence[float] | None = ...,

lib/matplotlib/tests/test_table.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,20 @@ def __repr__(self):
253253

254254
munits.registry.pop(FakeUnit)
255255
assert not munits.registry.get_converter(FakeUnit)
256+
257+
258+
def test_table_dataframe(pd):
259+
# Test if Pandas Data Frame can be passed in cellText
260+
261+
data = {
262+
'Letter': ['A', 'B', 'C'],
263+
'Number': [100, 200, 300]
264+
}
265+
266+
df = pd.DataFrame(data)
267+
fig, ax = plt.subplots()
268+
table = ax.table(df, loc='center')
269+
270+
for r, (index, row) in enumerate(df.iterrows()):
271+
for c, col in enumerate(df.columns if r == 0 else row.values):
272+
assert table[r if r == 0 else r+1, c].get_text().get_text() == str(col)

0 commit comments

Comments
 (0)