Source code for holoviews.plotting.tabular

from collections import defaultdict
from matplotlib.font_manager import FontProperties
from matplotlib.table import Table as mpl_Table

import param

from ..element import ItemTable, Table
from .element import ElementPlot
from ..core.options import Store
from ..core.util import safe_unicode


[docs]class TablePlot(ElementPlot): """ A TablePlot can plot both TableViews and ViewMaps which display as either a single static table or as an animated table respectively. """ border = param.Number(default=0.05, bounds=(0.0, 0.5), doc=""" The fraction of the plot that should be empty around the edges.""") float_precision = param.Integer(default=3, doc=""" The floating point precision to use when printing float numeric data types.""") max_value_len = param.Integer(default=20, doc=""" The maximum allowable string length of a value shown in any table cell. Any strings longer than this length will be truncated.""") max_font_size = param.Integer(default=12, doc=""" The largest allowable font size for the text in each table cell.""") max_rows = param.Integer(default=15, doc=""" The maximum number of Table rows before the table is summarized.""") font_types = param.Dict(default={'heading': FontProperties(weight='bold', family='DejaVu Sans')}, doc="""The font style used for heading labels used for emphasis.""") style_opts = ['alpha', 'sketch_params'] # Disable computing plot bounds from data. apply_databounds = False def __init__(self, table, **params): super(TablePlot, self).__init__(table, **params) self.cell_values, self.cell_widths = self._format_table() def _format_table(self): cell_values = defaultdict(dict) cell_widths = defaultdict(int) for key in self.keys: frame = self._get_frame(key) if frame is None: continue # Mapping from the cell coordinates to the dictionary key. summarize = frame.rows > self.max_rows half_rows = self.max_rows/2 rows = min([self.max_rows, frame.rows]) for row in range(rows): adjusted_row = row for col in range(frame.cols): if summarize and row == half_rows: cell_text = "..." else: if summarize and row > half_rows: adjusted_row = (frame.rows - self.max_rows + row) value = frame.pprint_cell(adjusted_row, col) cell_text = self.pprint_value(value) cell_values[key][(row, col)] = cell_text if len(cell_text) + 2 > cell_widths[col]: cell_widths[col] = len(cell_text) + 2 return cell_values, cell_widths
[docs] def pprint_value(self, value): """ Generate the pretty printed representation of a value for inclusion in a table cell. """ if isinstance(value, float): formatter = '{:.%df}' % self.float_precision formatted = formatter.format(value) elif isinstance(value, str): formatted = safe_unicode(value) else: formatted = str(value) if len(formatted) > self.max_value_len: return formatted[:(self.max_value_len-3)]+'...' else: return formatted
def __call__(self, ranges=None): element = self.map.last axis = self.handles['axis'] axis.set_axis_off() size_factor = (1.0 - 2*self.border) table = mpl_Table(axis, bbox=[self.border, self.border, size_factor, size_factor]) total_width = sum(self.cell_widths.values()) height = size_factor / element.rows summarize = element.rows > self.max_rows half_rows = self.max_rows/2 rows = min([self.max_rows, element.rows]) for row in range(rows): adjusted_row = row for col in range(element.cols): if summarize and row > half_rows: adjusted_row = (element.rows - self.max_rows + row) cell_value = self.cell_values[self.keys[-1]][(row, col)] cellfont = self.font_types.get(element.cell_type(adjusted_row,col), None) width = self.cell_widths[col] / float(total_width) font_kwargs = dict(fontproperties=cellfont) if cellfont else {} table.add_cell(row, col, width, height, text=cell_value, loc='center', **font_kwargs) table.set_fontsize(self.max_font_size) table.auto_set_font_size(True) axis.add_table(table) self.handles['table'] = table return self._finalize_axis(self.keys[-1]) def update_handles(self, axis, view, key, ranges=None): table = self.handles['table'] for coords, cell in table.get_celld().items(): value = self.cell_values[key][coords] cell.set_text_props(text=value) # Resize fonts across table as necessary table.set_fontsize(self.max_font_size) table.auto_set_font_size(True)
Store.registry.update({ItemTable: TablePlot, Table: TablePlot})