Matplotlib 表格没有“colspan”或“rowspan”的概念,其中单元格跨越多列或多行。人们可以认为一个单元格的宽度可以是其他单元格的三倍。但是,这会带来不必要的转变
您可以选择将您通过.add_cell 手动添加的其他单元格的visible_edges 设置到表格顶部。
可见边缘可以是"T":顶部、"B":底部、"L":左侧或"R":右侧。
然后将文本设置为中间单元格,使整个内容看起来像一个单元格。
import matplotlib.pyplot as plt
data = [[1,2,3,4],[6,5,4,3],[1,3,5,1]]
table = plt.table(cellText=data, colLabels=['A', 'B', 'C', 'D'], loc='center',
cellLoc='center', colColours=['#FFFFFF', '#F3CC32', '#2769BD', '#DC3735'])
table.auto_set_font_size(False)
h = table.get_celld()[(0,0)].get_height()
w = table.get_celld()[(0,0)].get_width()
# Create an additional Header
header = [table.add_cell(-1,pos, w, h, loc="center", facecolor="none") for pos in [1,2,3]]
header[0].visible_edges = "TBL"
header[1].visible_edges = "TB"
header[2].visible_edges = "TBR"
header[1].get_text().set_text("Header Header Header Header")
plt.axis('off')
plt.show()
附录
以上内容不允许为表格单元格的背景着色。为此,可以使用以下解决方法:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.table
from matplotlib.collections import LineCollection
from matplotlib.path import Path
class MyCell(matplotlib.table.CustomCell):
def __init__(self, *args, visible_edges, **kwargs):
super().__init__(*args, visible_edges=visible_edges, **kwargs)
seg = np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0],
[0.0, 1.0], [0.0, 0.0]]).reshape(-1, 1, 2)
segments = np.concatenate([seg[:-1], seg[1:]], axis=1)
self.edgelines = LineCollection(segments, edgecolor=kwargs.get("edgecolor"))
self._text.set_zorder(2)
self.set_zorder(1)
def set_transform(self, trans):
self.edgelines.set_transform(trans)
super().set_transform(trans)
def draw(self, renderer):
c = self.get_edgecolor()
self.set_edgecolor((1,1,1,0))
super().draw(renderer)
self.update_segments(c)
self.edgelines.draw(renderer)
self.set_edgecolor(c)
def update_segments(self, color):
x, y = self.get_xy()
w, h = self.get_width(), self.get_height()
seg = np.array([[x, y], [x+w, y], [x+w, y+h],
[x, y+h], [x, y]]).reshape(-1, 1, 2)
segments = np.concatenate([seg[:-1], seg[1:]], axis=1)
self.edgelines.set_segments(segments)
self.edgelines.set_linewidth(self.get_linewidth())
colors = [color if edge in self._visible_edges else (1,1,1,0)
for edge in self._edges]
self.edgelines.set_edgecolor(colors)
def get_path(self):
codes = [Path.MOVETO] + [Path.LINETO]*3 + [Path.CLOSEPOLY]
return Path(
[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]],
codes, readonly=True)
matplotlib.table.CustomCell = MyCell
data = [[1,2,3,4],[6,5,4,3],[1,3,5,1]]
table = plt.table(cellText=data, colLabels=['A', 'B', 'C', 'D'], loc='center',
cellLoc='center', colColours=['#FFFFFF', '#F3CC32', '#2769BD', '#DC3735'])
table.auto_set_font_size(False)
h = table.get_celld()[(0,0)].get_height()
w = table.get_celld()[(0,0)].get_width()
# Create an additional Header
header = [table.add_cell(-1,pos, w, h, loc="center", facecolor="limegreen") for pos in [1,2,3]]
header[0].visible_edges = "TBL"
header[1].visible_edges = "TB"
header[2].visible_edges = "TBR"
header[1].get_text().set_text("Header")
plt.axis('off')
plt.show()
但是请注意,由于绘图顺序,如果标题文本比单元格长,这将失败。