diff --git a/pandas/io/api.py b/pandas/io/api.py index dc9ea290eb45e..ca62a68d85ddc 100644 --- a/pandas/io/api.py +++ b/pandas/io/api.py @@ -12,3 +12,4 @@ from pandas.io.stata import read_stata from pandas.io.pickle import read_pickle, to_pickle from pandas.io.packers import read_msgpack, to_msgpack +from pandas.io.templating import HTMLStyler \ No newline at end of file diff --git a/pandas/io/templating/__init__.py b/pandas/io/templating/__init__.py new file mode 100644 index 0000000000000..da7cfd3e58d3d --- /dev/null +++ b/pandas/io/templating/__init__.py @@ -0,0 +1,114 @@ +from abc import abstractmethod +import os +import uuid + + +ROW_HEADING_CLASS = "pandas_row_heading" +COL_HEADING_CLASS = "pandas_col_heading" +DATA_CLASS = "pandas_data" +DATA_CELL_TYPE = "data" +ROW_CLASS = "pandas_row" +COLUMN_CLASS = "pandas_col" +HEADING_CELL_TYPE = "heading" +BLANK_CLASS = "pandas_blank" +BLANK_VALUE = "" +LEVEL_CLASS = "pandas_level" + +TEMPLATE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), + "templates") + +# TODO, cleaner handling of cell_context (extra_contaxt +class Styler(object): + + @abstractmethod + def render(self, f): + pass + + def __init__(self, df, template, engine_instance=None,*args, **kwds): + super(Styler, self).__init__(*args, **kwds) + self.df = df + self.template = template + self.style = [] + self.cell_context = {} + + from pandas.io.templating.engines import Jinja2Engine + self.engine_instance = engine_instance or Jinja2Engine() + self.engine_instance.load(self.template) + + def std_context(self, *args, **kwds): + df = self.df + + n_rlvls = df.index.nlevels + n_clvls = df.columns.nlevels + rlabels = df.index.tolist() + clabels = df.columns.tolist() + if n_rlvls == 1: + rlabels = [[x] for x in rlabels] + if n_clvls == 1: + clabels = [[x] for x in clabels] + clabels = zip(*clabels) + head = [] + for r in range(n_clvls): + row_es = [{"type": HEADING_CELL_TYPE, "value": BLANK_VALUE, + "class": " ".join([BLANK_CLASS])}] * n_rlvls + for c in range(len(clabels[0])): + cs = [COL_HEADING_CLASS, "%s%s" % (LEVEL_CLASS, r), + "%s%s" % (COLUMN_CLASS, c)] + cs.extend( + self.cell_context.get("col_headings", {}).get(r, {}).get(c, + [])) + row_es.append( + {"type": HEADING_CELL_TYPE, "value": clabels[r][c], + "class": " ".join(cs)}) + head.append(row_es) + body = [] + for r in range(len(df)): + cs = [ROW_HEADING_CLASS, "%s%s" % (LEVEL_CLASS, c), + "%s%s" % (ROW_CLASS, r)] + cs.extend( + self.cell_context.get("row_headings", {}).get(r, {}).get(c, [])) + row_es = [ + {"type": HEADING_CELL_TYPE, "value": rlabels[r][c], + "class": " ".join(cs)} + for c in range(len(rlabels[r]))] + for c in range(len(df.columns)): + cs = [DATA_CLASS, "%s%s" % (ROW_CLASS, r), + "%s%s" % (COLUMN_CLASS, c)] + cs.extend( + self.cell_context.get("data", {}).get(r, {}).get(c, [])) + row_es.append( + {"type": DATA_CELL_TYPE, "value": df.iloc[r][c], + "class": " ".join(cs)}) + body.append(row_es) + + # uuid required to isolate table styling from other tables + # on the page in ipnb + u = str(uuid.uuid1()).replace("-", "_") + return dict(head=head, body=body, uuid=u, style=self.style) + + def render(self, f=None, **kwds): + encoding = kwds.pop('encoding', "utf8") + s = self.engine_instance.render(self.std_context()) + if f: + with codecs.open(f, "wb", encoding) as f: + f.write(s) + else: + return s + +class ITemplateEngine(object): + """Interface for supporting multiple template engines + + We'll support only a single engine, but help users help themselves. + """ + + + @abstractmethod + def render(self, f=None,**kwds): + pass + + @abstractmethod + def load(self, *args, **kwds): + pass + + +from html import HTMLStyler \ No newline at end of file diff --git a/pandas/io/templating/colors.py b/pandas/io/templating/colors.py new file mode 100644 index 0000000000000..f9b6d0873a6a2 --- /dev/null +++ b/pandas/io/templating/colors.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function + +import sys, os, re, json, codecs + +# integrate some colorbrewer package +red_scale = ["#fff7ec", "#fee8c8", "#fdd49e", + "#fdbb84", "#fc8d59", "#ef6548", + "#d7301f", "#b30000", "#7f0000"] \ No newline at end of file diff --git a/pandas/io/templating/engines.py b/pandas/io/templating/engines.py new file mode 100644 index 0000000000000..bb9c146bcd641 --- /dev/null +++ b/pandas/io/templating/engines.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from pandas.io.templating import ITemplateEngine + + +class Jinja2Engine(ITemplateEngine): + def __init__(self): + from jinja2 import Template + + def load(self, s): + from jinja2 import Template + + self.t = Template(s) + + def render(self, ctx): + if self.t: + return self.t.render(**ctx) + else: + raise AssertionError("Template not initialized, cannot render") \ No newline at end of file diff --git a/pandas/io/templating/html.py b/pandas/io/templating/html.py new file mode 100644 index 0000000000000..2a35b81a726bc --- /dev/null +++ b/pandas/io/templating/html.py @@ -0,0 +1,64 @@ +import uuid +import os +import functools +from os.path import abspath, dirname + +from pandas.io.templating import * + + +# TODO: caption + +class HTMLStyler(Styler): + def clone(self): + """We always return a modified copy when extra styling is added + + `clone()` provides a copy to apply changes to + """ + import copy + + c = HTMLStyler(self.df, + template=self.template, + engine_instance=self.engine_instance) + c.style = copy.deepcopy(self.style) + c.cell_context = copy.deepcopy(self.cell_context) + return c + + def __init__(self, *args, **kwds): + + if not kwds.get('template'): + tmpl_filename = os.path.join(TEMPLATE_DIR, "html") + with open(tmpl_filename) as f: + kwds['template'] = f.read() + + super(HTMLStyler, self).__init__(*args, **kwds) + + import html_helpers + import types + + for n in dir(html_helpers): + cand = getattr(html_helpers, n) + if callable(cand): + def f(cand): + @functools.wraps(cand) + def f(self, *args, **kwds): + self_copy = self.clone() + cand(self_copy, *args, **kwds) + # self.style.extend(sd.style) + # TODO, need to merge-with + # self.cell_context = sd.cell_context + return self_copy + + return f + + setattr(self, n, types.MethodType(f(cand), self)) + + def _repr_html_(self): + return self.render() + + # def __dir__(self): + # import html_helpers + # return ["render","to_context"] + dir(html_helpers) + + # def __getattr__(self, key): + # import html_helpers + # return getattr(html_helpers,key) \ No newline at end of file diff --git a/pandas/io/templating/html_helpers.py b/pandas/io/templating/html_helpers.py new file mode 100644 index 0000000000000..dd158ceede6f7 --- /dev/null +++ b/pandas/io/templating/html_helpers.py @@ -0,0 +1,138 @@ +from __future__ import print_function + +import sys, os, re, json, codecs +import uuid + +from pandas.io.templating import * + +__all__ = ["zebra", "hlrow", "hlcol"] + +from collections import namedtuple + + +def zebra(s, color1, color2): + style = [dict(selector="td.%s:nth-child(2n)" % DATA_CLASS, + props=[("background-color", color1)]), + dict(selector="td.%s:nth-child(2n+1)" % DATA_CLASS, + props=[("background-color", color2)])] + s.style.extend(style) + + +def hlcell(s, r, c, color="#aaa", with_headings=False): + selector = "td.%s%d.%s%d" % (ROW_CLASS, r, COLUMN_CLASS, c) + if not with_headings: + selector += ".%s" % DATA_CLASS + style = [dict(selector=selector, + props=[("background-color", color)])] + s.style.extend(style) + + +def hlcol(s, n, color="#aaa", with_headings=False): + selector = "td.%s%d" % (COLUMN_CLASS, n) + if not with_headings: + selector += ".%s" % DATA_CLASS + style = [dict(selector=selector, + props=[("background-color", color)])] + s.style.extend(style) + + +def hlrow(s, n, color="#ccc", with_headings=False): + selector = "td.%s%d" % (ROW_CLASS, n) + if not with_headings: + selector += ".%s" % DATA_CLASS + style = [dict(selector=selector, + props=[("background-color", color)])] + s.style.extend(style) + + +def round_corners(s, radius): + props_bl = [ + ("-moz-border-radius-bottomleft", "%dpx" % radius ), + ("-webkit-border-bottom-left-radius", "%dpx" % radius ), + ("border-bottom-left-radius", "%dpx" % radius ) + ] + props_br = [ + ("-moz-border-radius-bottomright", "%dpx" % radius ), + ("-webkit-border-bottom-right-radius", "%dpx" % radius ), + ("border-bottom-right-radius", "%dpx" % radius ) + ] + props_tl = [ + ("-moz-border-radius-topleft", "%dpx" % radius ), + ("-webkit-border-top-left-radius", "%dpx" % radius ), + ("border-top-left-radius", "%dpx" % radius ) + ] + props_tr = [ + ("-moz-border-radius-topright", "%dpx" % radius ), + ("-webkit-border-top-right-radius", "%dpx" % radius ), + ("border-top-right-radius", "%dpx" % radius ) + ] + + style = [ + dict(selector="", + props=[("border-collapse", "separate")]), + dict(selector="td", + props=[("border-width", "0px")]), + dict(selector="th", + props=[("border-width", "0px")]), + dict(selector="td", + props=[("border-left-width", "1px")]), + dict(selector="td", + props=[("border-top-width", "1px")]), + + dict(selector="tbody tr:last-child th", + props=[("border-bottom-width", "1px")]), + dict(selector="tr:last-child td", + props=[("border-bottom-width", "1px")]), + + dict(selector="tr td:last-child", + props=[("border-right-width", "1px")]), + dict(selector="tr th:last-child", + props=[("border-right-width", "1px")]), + dict(selector="th", + props=[("border-left-width", "1px")]), + dict(selector="th", + props=[("border-top-width", "1px")]), + dict(selector="th td:last-child", + props=[("border-right-width", "1px")]), + + + dict(selector="tr:last-child th:first-child", + props=props_bl), + dict(selector="tr:last-child td:last-child", + props=props_br), + dict(selector="tr:first-child th.%s0" % COLUMN_CLASS, + props=props_tl), + dict(selector="tr:first-child th.%s0:first-child" % ROW_CLASS, + props=props_tl), + dict(selector="tr:first-child th:last-child", + props=props_tr), + ] + + s.style.extend(style) + +# +# def rank_heatmap(s, df, row=None, col=None): +# def color_class(cls, color): +# return [dict(selector="td.%s" % cls, +# props=[("background-color", color)])] +# +# def rank_col(n, ranking, u): +# data = {i: {n: ["%s-%s" % (u, ranking[i])]} +# for i in range(len(ranking))} +# return {"data": data} +# +# +# # u = "U" + str(uuid.uuid1()).replace("-", "_") +# # df = mkdf(9, 5, data_gen_f=lambda r, c: np.random.random()) +# +# ranking = df.iloc[:, 1].argsort().tolist() +# cell_context = rank_col(1, ranking, u) +# +# from .colors import red_scale +# +# style = [color_class("%s-%s" % (u, intensity), +# red_scale[intensity]) +# for intensity in range(9)] +# +# s.style.extend(style) +# # s.cell_context.extend(s) # TODO diff --git a/pandas/io/templating/templates/html b/pandas/io/templating/templates/html new file mode 100644 index 0000000000000..a9fa90385c793 --- /dev/null +++ b/pandas/io/templating/templates/html @@ -0,0 +1,61 @@ +{#jinja2 template#} + + + + + + {% if caption %} + + {% endif %} + + + {% for r in head %} + + {% for c in r %} + {% if c.type == "heading" %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + + + + {% for r in body %} + + {% for c in r %} + {% if c.type == "heading" %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + + +
+ {{ caption }} +
{{ c.value }}{{ c.value }}
{{ c.value }}{{ c.value }}
\ No newline at end of file diff --git a/pandas/io/templating/templates/latex b/pandas/io/templating/templates/latex new file mode 100644 index 0000000000000..f7440e0a925ad --- /dev/null +++ b/pandas/io/templating/templates/latex @@ -0,0 +1,23 @@ +{#jinja2 template#} + +\documentclass[11pt,a4paper]{article} +\usepackage{booktabs} + +\begin{document} + +\begin{tabular}{ {% for c in body[0] %}l{% endfor %} } + +\toprule + {% for r in head %} + {% for c in r[:-1] %}{{ c.value }} & {% endfor %} {{ r[-1].value }} \\ + {%- endfor %} + +\midrule + {% for r in body %} + {% for c in r[:-1] %}{{ c.value }} & {% endfor %} {{ r[-1].value }} \\ + {%- endfor %} +\bottomrule + +\end{tabular} + +\end{document} \ No newline at end of file diff --git a/pandas/io/templating/templates/markdown b/pandas/io/templating/templates/markdown new file mode 100644 index 0000000000000..82397df703263 --- /dev/null +++ b/pandas/io/templating/templates/markdown @@ -0,0 +1,21 @@ +{# jinja2 template #} + +{% for r in head %} +|{%- for c in r -%} + {%- if c.type == "heading" and "blank" not in c.class -%} + __{{ c.value }}__ | + {%- else -%} + {{ c.value }} | + {%- endif -%} +{%- endfor %} +{%- endfor %} +| {% for c in head[0] %} --- | {% endfor -%} +{% for r in body %} +|{%- for c in r -%} + {%- if c.type == "heading" -%} + __{{ c.value }}__ | + {%- else -%} + {{ c.value }} | + {%- endif -%} +{% endfor %} +{%- endfor %} \ No newline at end of file diff --git a/pandas_HTML_styling.ipynb b/pandas_HTML_styling.ipynb new file mode 100644 index 0000000000000..a2f52eac167e9 --- /dev/null +++ b/pandas_HTML_styling.ipynb @@ -0,0 +1,1809 @@ +{ + "metadata": { + "name": "" + }, + "nbformat": 3, + "nbformat_minor": 0, + "worksheets": [ + { + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "###Conditional Formatting and CSS support for HTML in pandas\n", + "\n", + "This is a preview of functionality planned for inclusion in pandas 0.14.\n", + "\n", + "####Overview\n", + "\n", + "* We render HTML output using a template engine, Jinja2.\n", + "* The template engine renders a data object using the specified template. \n", + "* The data object (\"context\") we pass in contains a structured representation of the dataframe and, importantly, the css class names to attach to any given cell.\n", + "* The classes attached to any given cell are the union of two sources:\n", + " 1. *Required classes* are attached to table cells by default, as part of the standard context object constructed by pandas for a specific dataframe. Examples of classes are: \"col_heading\"/\"row_heading\"/\"data\", \"row0\",\"col3\". etc\n", + " 2. An additional nested dict (`cell_context`, provisional name) is passed in which can optionally attach classes to specific cells. e.g. `{data:{0:{2:[\"foo\"]}` will attach the class \"foo\" to the the data cell at df.iloc[0,2].\n", + "* since `cell_context` is constructed dynamically, we can construct \"styler\" functions that inspect the dataframe and attach arbitrary classes to various table cells by whatever logic we can express in code (i.e. anything).\n", + "* The actual styling is done using inline css which is included in the rendered HTML. The template context contains a style property, also produced dynamically by code, which can specify any selector + css property/value pair to be included in the inline `\n", + "\n", + "{% if caption %}\n", + "\n", + "{% endif %}\n", + "\n", + " \n", + "{% for r in head %}\n", + " \n", + " {% for c in r %} \n", + " <{{c.type}} class=\"{{c.class}}\">{{c.value}}\n", + " {% endfor %}\n", + " \n", + "{% endfor %}\n", + " \n", + " \n", + " {% for r in body %}\n", + " \n", + " {% for c in r %} \n", + " <{{c.type}} class=\"{{c.class}}\">{{c.value}}\n", + " {% endfor %}\n", + " \n", + "{% endfor %}\n", + " \n", + "\n", + "
\n", + "{{caption}}\n", + "
\n", + "\n", + "\"\"\")" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 3 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "# the implementation code. very small.\n", + "ROW_HEADING_CLASS=\"row_heading\"\n", + "COL_HEADING_CLASS=\"col_heading\"\n", + "DATA_CLASS=\"data\"\n", + "BLANK_CLASS=\"blank\"\n", + "BLANK_VALUE=\"\"\n", + "def translate(df,cell_context=None):\n", + " import uuid\n", + " cell_context = cell_context or dict()\n", + "\n", + " n_rlvls =df.index.nlevels\n", + " n_clvls =df.columns.nlevels\n", + " rlabels=df.index.tolist()\n", + " clabels=df.columns.tolist()\n", + " if n_rlvls == 1:\n", + " rlabels = [[x] for x in rlabels]\n", + " if n_clvls == 1:\n", + " clabels = [[x] for x in clabels]\n", + " clabels=zip(*clabels) \n", + " head=[]\n", + " for r in range(n_clvls): \n", + " row_es = [{\"type\":\"th\",\"value\":BLANK_VALUE ,\"class\": \" \".join([BLANK_CLASS])}]*n_rlvls\n", + " for c in range(len(clabels[0])):\n", + " cs = [COL_HEADING_CLASS,\"level%s\" % r,\"col%s\" %c]\n", + " cs.extend(cell_context.get(\"col_headings\",{}).get(r,{}).get(c,[]))\n", + " row_es.append({\"type\":\"th\",\"value\": clabels[r][c],\"class\": \" \".join(cs)})\n", + " head.append(row_es)\n", + " body=[]\n", + " for r in range(len(df)): \n", + " cs = [ROW_HEADING_CLASS,\"level%s\" % c,\"row%s\" % r]\n", + " cs.extend(cell_context.get(\"row_headings\",{}).get(r,{}).get(c,[]))\n", + " row_es = [{\"type\":\"th\",\"value\": rlabels[r][c],\"class\": \" \".join(cs)} \n", + " for c in range(len(rlabels[r]))]\n", + " for c in range(len(df.columns)):\n", + " cs = [DATA_CLASS,\"row%s\" % r,\"col%s\" %c]\n", + " cs.extend(cell_context.get(\"data\",{}).get(r,{}).get(c,[]))\n", + " row_es.append({\"type\":\"td\",\"value\": df.iloc[r][c],\"class\": \" \".join(cs)})\n", + " body.append(row_es)\n", + "\n", + " # uuid required to isolate table styling from others \n", + " # in same notebook in ipnb\n", + " u = str(uuid.uuid1()).replace(\"-\",\"_\")\n", + " return dict(head=head, body=body,uuid=u)\n" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 4 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##Examples" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "# first, vanilla\n", + "df=mkdf(10,5,r_idx_nlevels=3,c_idx_nlevels=2)\n", + "from IPython.display import HTML,display\n", + "ctx= translate(df)\n", + "ctx['caption']=\"Just a table, but rendered using a template with lots of classes to style against\"\n", + "display(HTML(t.render(**ctx)))\n" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + "\n", + "
\n", + "Just a table, but rendered using a template with lots of classes to style against\n", + "
C_l0_g0C_l0_g1C_l0_g2C_l0_g3C_l0_g4
C_l1_g0C_l1_g1C_l1_g2C_l1_g3C_l1_g4
R_l0_g0R_l1_g0R_l2_g0R0C0\n", + " \n", + " R0C1\n", + " \n", + " R0C2\n", + " \n", + " R0C3\n", + " \n", + " R0C4\n", + " \n", + "
R_l0_g1R_l1_g1R_l2_g1R1C0\n", + " \n", + " R1C1\n", + " \n", + " R1C2\n", + " \n", + " R1C3\n", + " \n", + " R1C4\n", + " \n", + "
R_l0_g2R_l1_g2R_l2_g2R2C0\n", + " \n", + " R2C1\n", + " \n", + " R2C2\n", + " \n", + " R2C3\n", + " \n", + " R2C4\n", + " \n", + "
R_l0_g3R_l1_g3R_l2_g3R3C0\n", + " \n", + " R3C1\n", + " \n", + " R3C2\n", + " \n", + " R3C3\n", + " \n", + " R3C4\n", + " \n", + "
R_l0_g4R_l1_g4R_l2_g4R4C0\n", + " \n", + " R4C1\n", + " \n", + " R4C2\n", + " \n", + " R4C3\n", + " \n", + " R4C4\n", + " \n", + "
R_l0_g5R_l1_g5R_l2_g5R5C0\n", + " \n", + " R5C1\n", + " \n", + " R5C2\n", + " \n", + " R5C3\n", + " \n", + " R5C4\n", + " \n", + "
R_l0_g6R_l1_g6R_l2_g6R6C0\n", + " \n", + " R6C1\n", + " \n", + " R6C2\n", + " \n", + " R6C3\n", + " \n", + " R6C4\n", + " \n", + "
R_l0_g7R_l1_g7R_l2_g7R7C0\n", + " \n", + " R7C1\n", + " \n", + " R7C2\n", + " \n", + " R7C3\n", + " \n", + " R7C4\n", + " \n", + "
R_l0_g8R_l1_g8R_l2_g8R8C0\n", + " \n", + " R8C1\n", + " \n", + " R8C2\n", + " \n", + " R8C3\n", + " \n", + " R8C4\n", + " \n", + "
R_l0_g9R_l1_g9R_l2_g9R9C0\n", + " \n", + " R9C1\n", + " \n", + " R9C2\n", + " \n", + " R9C3\n", + " \n", + " R9C4\n", + " \n", + "
\n" + ], + "metadata": {}, + "output_type": "display_data", + "text": [ + "" + ] + } + ], + "prompt_number": 5 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def zebra(color1, color2):\n", + " return [dict(selector=\"td.data:nth-child(2n)\" ,\n", + " props=[(\"background-color\",color1)]),\n", + " dict(selector=\"td.data:nth-child(2n+1)\" ,\n", + " props=[(\"background-color\",color2)])]\n", + "\n", + "ctx= translate(df)\n", + "style=[]\n", + "style.extend(zebra(\"#aaa\",\"#ddd\"))\n", + "ctx['style']=style\n", + "ctx['caption']=\"A zebra table\"\n", + "display(HTML(t.render(**ctx)))\n" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + "\n", + "
\n", + "A zebra table\n", + "
C_l0_g0C_l0_g1C_l0_g2C_l0_g3C_l0_g4
C_l1_g0C_l1_g1C_l1_g2C_l1_g3C_l1_g4
R_l0_g0R_l1_g0R_l2_g0R0C0\n", + " \n", + " R0C1\n", + " \n", + " R0C2\n", + " \n", + " R0C3\n", + " \n", + " R0C4\n", + " \n", + "
R_l0_g1R_l1_g1R_l2_g1R1C0\n", + " \n", + " R1C1\n", + " \n", + " R1C2\n", + " \n", + " R1C3\n", + " \n", + " R1C4\n", + " \n", + "
R_l0_g2R_l1_g2R_l2_g2R2C0\n", + " \n", + " R2C1\n", + " \n", + " R2C2\n", + " \n", + " R2C3\n", + " \n", + " R2C4\n", + " \n", + "
R_l0_g3R_l1_g3R_l2_g3R3C0\n", + " \n", + " R3C1\n", + " \n", + " R3C2\n", + " \n", + " R3C3\n", + " \n", + " R3C4\n", + " \n", + "
R_l0_g4R_l1_g4R_l2_g4R4C0\n", + " \n", + " R4C1\n", + " \n", + " R4C2\n", + " \n", + " R4C3\n", + " \n", + " R4C4\n", + " \n", + "
R_l0_g5R_l1_g5R_l2_g5R5C0\n", + " \n", + " R5C1\n", + " \n", + " R5C2\n", + " \n", + " R5C3\n", + " \n", + " R5C4\n", + " \n", + "
R_l0_g6R_l1_g6R_l2_g6R6C0\n", + " \n", + " R6C1\n", + " \n", + " R6C2\n", + " \n", + " R6C3\n", + " \n", + " R6C4\n", + " \n", + "
R_l0_g7R_l1_g7R_l2_g7R7C0\n", + " \n", + " R7C1\n", + " \n", + " R7C2\n", + " \n", + " R7C3\n", + " \n", + " R7C4\n", + " \n", + "
R_l0_g8R_l1_g8R_l2_g8R8C0\n", + " \n", + " R8C1\n", + " \n", + " R8C2\n", + " \n", + " R8C3\n", + " \n", + " R8C4\n", + " \n", + "
R_l0_g9R_l1_g9R_l2_g9R9C0\n", + " \n", + " R9C1\n", + " \n", + " R9C2\n", + " \n", + " R9C3\n", + " \n", + " R9C4\n", + " \n", + "
\n" + ], + "metadata": {}, + "output_type": "display_data", + "text": [ + "" + ] + } + ], + "prompt_number": 6 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def tag_col(n,c=\"grey10\", with_headings=False):\n", + " selector=\"td.col%d\" % n\n", + " if not with_headings:\n", + " selector+=\".data\"\n", + " return [dict(selector=selector,\n", + " props=[(\"background-color\",c)])]\n", + "\n", + "def tag_row(n,c=\"grey10\", with_headings=False):\n", + " selector=\"td.row%d\" % n\n", + " if not with_headings:\n", + " selector+=\".data\"\n", + " return [dict(selector=selector,\n", + " props=[(\"background-color\",c)])]\n", + "\n", + "ctx= translate(df)\n", + "style=[]\n", + "style.extend(tag_col(2,\"beige\"))\n", + "style.extend(tag_row(3,\"purple\"))\n", + "ctx['style']=style\n", + "ctx['caption']=\"Highlight rows/cols by index\"\n", + "display(HTML(t.render(**ctx)))\n" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + "\n", + "
\n", + "Highlight rows/cols by index\n", + "
C_l0_g0C_l0_g1C_l0_g2C_l0_g3C_l0_g4
C_l1_g0C_l1_g1C_l1_g2C_l1_g3C_l1_g4
R_l0_g0R_l1_g0R_l2_g0R0C0\n", + " \n", + " R0C1\n", + " \n", + " R0C2\n", + " \n", + " R0C3\n", + " \n", + " R0C4\n", + " \n", + "
R_l0_g1R_l1_g1R_l2_g1R1C0\n", + " \n", + " R1C1\n", + " \n", + " R1C2\n", + " \n", + " R1C3\n", + " \n", + " R1C4\n", + " \n", + "
R_l0_g2R_l1_g2R_l2_g2R2C0\n", + " \n", + " R2C1\n", + " \n", + " R2C2\n", + " \n", + " R2C3\n", + " \n", + " R2C4\n", + " \n", + "
R_l0_g3R_l1_g3R_l2_g3R3C0\n", + " \n", + " R3C1\n", + " \n", + " R3C2\n", + " \n", + " R3C3\n", + " \n", + " R3C4\n", + " \n", + "
R_l0_g4R_l1_g4R_l2_g4R4C0\n", + " \n", + " R4C1\n", + " \n", + " R4C2\n", + " \n", + " R4C3\n", + " \n", + " R4C4\n", + " \n", + "
R_l0_g5R_l1_g5R_l2_g5R5C0\n", + " \n", + " R5C1\n", + " \n", + " R5C2\n", + " \n", + " R5C3\n", + " \n", + " R5C4\n", + " \n", + "
R_l0_g6R_l1_g6R_l2_g6R6C0\n", + " \n", + " R6C1\n", + " \n", + " R6C2\n", + " \n", + " R6C3\n", + " \n", + " R6C4\n", + " \n", + "
R_l0_g7R_l1_g7R_l2_g7R7C0\n", + " \n", + " R7C1\n", + " \n", + " R7C2\n", + " \n", + " R7C3\n", + " \n", + " R7C4\n", + " \n", + "
R_l0_g8R_l1_g8R_l2_g8R8C0\n", + " \n", + " R8C1\n", + " \n", + " R8C2\n", + " \n", + " R8C3\n", + " \n", + " R8C4\n", + " \n", + "
R_l0_g9R_l1_g9R_l2_g9R9C0\n", + " \n", + " R9C1\n", + " \n", + " R9C2\n", + " \n", + " R9C3\n", + " \n", + " R9C4\n", + " \n", + "
\n" + ], + "metadata": {}, + "output_type": "display_data", + "text": [ + "" + ] + } + ], + "prompt_number": 7 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def round_corners(radius):\n", + " props_bl=[ \n", + " (\"-moz-border-radius-bottomleft\", \"%dpx\" % radius ),\n", + " (\"-webkit-border-bottom-left-radius\", \"%dpx\" % radius ),\n", + " (\"border-bottom-left-radius\", \"%dpx\" % radius )\n", + " ]\n", + " props_br=[ \n", + " (\"-moz-border-radius-bottomright\", \"%dpx\" % radius ),\n", + " (\"-webkit-border-bottom-right-radius\", \"%dpx\" % radius ),\n", + " (\"border-bottom-right-radius\", \"%dpx\" % radius )\n", + " ]\n", + " props_tl=[ \n", + " (\"-moz-border-radius-topleft\", \"%dpx\" % radius ),\n", + " (\"-webkit-border-top-left-radius\", \"%dpx\" % radius ),\n", + " (\"border-top-left-radius\", \"%dpx\" % radius )\n", + " ]\n", + " props_tr=[ \n", + " (\"-moz-border-radius-topright\", \"%dpx\" % radius ),\n", + " (\"-webkit-border-top-right-radius\", \"%dpx\" % radius ),\n", + " (\"border-top-right-radius\", \"%dpx\" % radius )\n", + " ] \n", + " \n", + " \n", + " return [dict(selector=\"td\",\n", + " props=[(\"border-width\",\"1px\")]),\n", + " dict(selector=\"\",\n", + " props=[(\"border-collapse\",\"separate\")]),\n", + " dict(selector=\"tr:last-child th:first-child\",\n", + " props=props_bl),\n", + " dict(selector=\"tr:last-child td:last-child\",\n", + " props=props_br),\n", + " dict(selector=\"tr:first-child th.col0\",\n", + " props=props_tl),\n", + " dict(selector=\"tr:first-child th.row0:first-child\",\n", + " props=props_tl), \n", + " dict(selector=\"tr:first-child th:last-child\",\n", + " props=props_tr),\n", + " ]\n", + " \n", + "ctx= translate(df)\n", + "style=[]\n", + "style.extend(round_corners(5))\n", + "\n", + "ctx['caption']=\"Rounded corners. CSS skills beginning to fail.\"\n", + "ctx['style']=style\n", + "display(HTML(t.render(**ctx)))\n" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + "\n", + "
\n", + "Rounded corners. CSS skills beginning to fail.\n", + "
C_l0_g0C_l0_g1C_l0_g2C_l0_g3C_l0_g4
C_l1_g0C_l1_g1C_l1_g2C_l1_g3C_l1_g4
R_l0_g0R_l1_g0R_l2_g0R0C0\n", + " \n", + " R0C1\n", + " \n", + " R0C2\n", + " \n", + " R0C3\n", + " \n", + " R0C4\n", + " \n", + "
R_l0_g1R_l1_g1R_l2_g1R1C0\n", + " \n", + " R1C1\n", + " \n", + " R1C2\n", + " \n", + " R1C3\n", + " \n", + " R1C4\n", + " \n", + "
R_l0_g2R_l1_g2R_l2_g2R2C0\n", + " \n", + " R2C1\n", + " \n", + " R2C2\n", + " \n", + " R2C3\n", + " \n", + " R2C4\n", + " \n", + "
R_l0_g3R_l1_g3R_l2_g3R3C0\n", + " \n", + " R3C1\n", + " \n", + " R3C2\n", + " \n", + " R3C3\n", + " \n", + " R3C4\n", + " \n", + "
R_l0_g4R_l1_g4R_l2_g4R4C0\n", + " \n", + " R4C1\n", + " \n", + " R4C2\n", + " \n", + " R4C3\n", + " \n", + " R4C4\n", + " \n", + "
R_l0_g5R_l1_g5R_l2_g5R5C0\n", + " \n", + " R5C1\n", + " \n", + " R5C2\n", + " \n", + " R5C3\n", + " \n", + " R5C4\n", + " \n", + "
R_l0_g6R_l1_g6R_l2_g6R6C0\n", + " \n", + " R6C1\n", + " \n", + " R6C2\n", + " \n", + " R6C3\n", + " \n", + " R6C4\n", + " \n", + "
R_l0_g7R_l1_g7R_l2_g7R7C0\n", + " \n", + " R7C1\n", + " \n", + " R7C2\n", + " \n", + " R7C3\n", + " \n", + " R7C4\n", + " \n", + "
R_l0_g8R_l1_g8R_l2_g8R8C0\n", + " \n", + " R8C1\n", + " \n", + " R8C2\n", + " \n", + " R8C3\n", + " \n", + " R8C4\n", + " \n", + "
R_l0_g9R_l1_g9R_l2_g9R9C0\n", + " \n", + " R9C1\n", + " \n", + " R9C2\n", + " \n", + " R9C3\n", + " \n", + " R9C4\n", + " \n", + "
\n" + ], + "metadata": {}, + "output_type": "display_data", + "text": [ + "" + ] + } + ], + "prompt_number": 8 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def color_class(cls, color):\n", + " return [dict(selector=\"td.%s\" % cls ,\n", + " props=[(\"background-color\",color)])]\n", + "def rank_col(n,ranking,u):\n", + " data = {i: {n: [\"%s-%s\" % (u,ranking[i])]} for i in range(len(ranking))}\n", + " return {\"data\": data}\n", + "\n", + "import uuid\n", + "u = \"U\"+str(uuid.uuid1()).replace(\"-\",\"_\")\n", + "df=mkdf(9,5,data_gen_f=lambda r,c:np.random.random())\n", + "\n", + "ranking=df.iloc[:,1].argsort().tolist()\n", + "cell_context=rank_col(1, ranking, u)\n", + "\n", + "ctx= translate(df,cell_context)\n", + "style=[]\n", + "# http://colorbrewer2.org/\n", + "color_scale=[\"#fff7ec\",\"#fee8c8\",\"#fdd49e\",\"#fdbb84\",\"#fc8d59\",\"#ef6548\",\"#d7301f\",\"#b30000\",\"#7f0000\"]\n", + "for intensity in range(9):\n", + " style.extend(color_class(\"%s-%s\" % (u,intensity),color_scale[intensity]))\n", + " \n", + "ctx['style']=style\n", + "ctx['caption']=\"And finally, a heatmap based on values\"\n", + "display(HTML(t.render(**ctx)))\n", + " " + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + "\n", + "
\n", + "And finally, a heatmap based on values\n", + "
C_l0_g0C_l0_g1C_l0_g2C_l0_g3C_l0_g4
R_l0_g00.211801747127\n", + " \n", + " 0.208803651856\n", + " \n", + " 0.743716623422\n", + " \n", + " 0.962017341688\n", + " \n", + " 0.176015213664\n", + " \n", + "
R_l0_g10.745491761131\n", + " \n", + " 0.820494510091\n", + " \n", + " 0.503137612941\n", + " \n", + " 0.238019828149\n", + " \n", + " 0.634250742128\n", + " \n", + "
R_l0_g20.569301755126\n", + " \n", + " 0.507672767903\n", + " \n", + " 0.309202712181\n", + " \n", + " 0.830732729127\n", + " \n", + " 0.617108870585\n", + " \n", + "
R_l0_g30.685515863149\n", + " \n", + " 0.985786341696\n", + " \n", + " 0.534988628544\n", + " \n", + " 0.900187936559\n", + " \n", + " 0.602678947775\n", + " \n", + "
R_l0_g40.521370083872\n", + " \n", + " 0.0110884722823\n", + " \n", + " 0.752014325914\n", + " \n", + " 0.520270090798\n", + " \n", + " 0.0095252937789\n", + " \n", + "
R_l0_g50.29865049643\n", + " \n", + " 0.1156016189\n", + " \n", + " 0.16250389458\n", + " \n", + " 0.1162681165\n", + " \n", + " 0.0624890733322\n", + " \n", + "
R_l0_g60.24039917756\n", + " \n", + " 0.831887982065\n", + " \n", + " 0.139444606684\n", + " \n", + " 0.87434203059\n", + " \n", + " 0.214273512954\n", + " \n", + "
R_l0_g70.0066042287924\n", + " \n", + " 0.333568312336\n", + " \n", + " 0.860660066709\n", + " \n", + " 0.273793599297\n", + " \n", + " 0.0247286858822\n", + " \n", + "
R_l0_g80.0372715722521\n", + " \n", + " 0.996144666822\n", + " \n", + " 0.258524096378\n", + " \n", + " 0.0665443054498\n", + " \n", + " 0.993389023817\n", + " \n", + "
\n" + ], + "metadata": {}, + "output_type": "display_data", + "text": [ + "" + ] + } + ], + "prompt_number": 9 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [], + "language": "python", + "metadata": {}, + "outputs": [] + } + ], + "metadata": {} + } + ] +} \ No newline at end of file diff --git a/pandas_HTML_styling_api.ipynb b/pandas_HTML_styling_api.ipynb new file mode 100644 index 0000000000000..abe53dea5b057 --- /dev/null +++ b/pandas_HTML_styling_api.ipynb @@ -0,0 +1,2151 @@ +{ + "metadata": { + "name": "" + }, + "nbformat": 3, + "nbformat_minor": 0, + "worksheets": [ + { + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "###Experimenting with the API" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "df=mkdf(10,5,r_idx_nlevels=2,c_idx_nlevels=3)\n", + "s=pd.io.templating.HTMLStyler(df) # -> df.to_styler()\n", + "s #vanilla" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "
C_l0_g0C_l0_g1C_l0_g2C_l0_g3C_l0_g4
C_l1_g0C_l1_g1C_l1_g2C_l1_g3C_l1_g4
C_l2_g0C_l2_g1C_l2_g2C_l2_g3C_l2_g4
R_l0_g0R_l1_g0R0C0R0C1R0C2R0C3R0C4
R_l0_g1R_l1_g1R1C0R1C1R1C2R1C3R1C4
R_l0_g2R_l1_g2R2C0R2C1R2C2R2C3R2C4
R_l0_g3R_l1_g3R3C0R3C1R3C2R3C3R3C4
R_l0_g4R_l1_g4R4C0R4C1R4C2R4C3R4C4
R_l0_g5R_l1_g5R5C0R5C1R5C2R5C3R5C4
R_l0_g6R_l1_g6R6C0R6C1R6C2R6C3R6C4
R_l0_g7R_l1_g7R7C0R7C1R7C2R7C3R7C4
R_l0_g8R_l1_g8R8C0R8C1R8C2R8C3R8C4
R_l0_g9R_l1_g9R9C0R9C1R9C2R9C3R9C4
" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 1, + "text": [ + "" + ] + } + ], + "prompt_number": 1 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "# vanilla-chocolate\n", + "# Should be vertical...\n", + "s.zebra(\"#ddd\",\"#eee\")" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "
C_l0_g0C_l0_g1C_l0_g2C_l0_g3C_l0_g4
C_l1_g0C_l1_g1C_l1_g2C_l1_g3C_l1_g4
C_l2_g0C_l2_g1C_l2_g2C_l2_g3C_l2_g4
R_l0_g0R_l1_g0R0C0R0C1R0C2R0C3R0C4
R_l0_g1R_l1_g1R1C0R1C1R1C2R1C3R1C4
R_l0_g2R_l1_g2R2C0R2C1R2C2R2C3R2C4
R_l0_g3R_l1_g3R3C0R3C1R3C2R3C3R3C4
R_l0_g4R_l1_g4R4C0R4C1R4C2R4C3R4C4
R_l0_g5R_l1_g5R5C0R5C1R5C2R5C3R5C4
R_l0_g6R_l1_g6R6C0R6C1R6C2R6C3R6C4
R_l0_g7R_l1_g7R7C0R7C1R7C2R7C3R7C4
R_l0_g8R_l1_g8R8C0R8C1R8C2R8C3R8C4
R_l0_g9R_l1_g9R9C0R9C1R9C2R9C3R9C4
" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 2, + "text": [ + "" + ] + } + ], + "prompt_number": 2 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "# cover your eyes\n", + "s.hlrow(4, \"green\").hlcol(2,\"purple\").hlcell(4,2,\"blue\")" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "
C_l0_g0C_l0_g1C_l0_g2C_l0_g3C_l0_g4
C_l1_g0C_l1_g1C_l1_g2C_l1_g3C_l1_g4
C_l2_g0C_l2_g1C_l2_g2C_l2_g3C_l2_g4
R_l0_g0R_l1_g0R0C0R0C1R0C2R0C3R0C4
R_l0_g1R_l1_g1R1C0R1C1R1C2R1C3R1C4
R_l0_g2R_l1_g2R2C0R2C1R2C2R2C3R2C4
R_l0_g3R_l1_g3R3C0R3C1R3C2R3C3R3C4
R_l0_g4R_l1_g4R4C0R4C1R4C2R4C3R4C4
R_l0_g5R_l1_g5R5C0R5C1R5C2R5C3R5C4
R_l0_g6R_l1_g6R6C0R6C1R6C2R6C3R6C4
R_l0_g7R_l1_g7R7C0R7C1R7C2R7C3R7C4
R_l0_g8R_l1_g8R8C0R8C1R8C2R8C3R8C4
R_l0_g9R_l1_g9R9C0R9C1R9C2R9C3R9C4
" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 14, + "text": [ + "" + ] + } + ], + "prompt_number": 14 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "s.round_corners(4)" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + "
C_l0_g0C_l0_g1C_l0_g2C_l0_g3C_l0_g4
C_l1_g0C_l1_g1C_l1_g2C_l1_g3C_l1_g4
C_l2_g0C_l2_g1C_l2_g2C_l2_g3C_l2_g4
R_l0_g0R_l1_g0R0C0R0C1R0C2R0C3R0C4
R_l0_g1R_l1_g1R1C0R1C1R1C2R1C3R1C4
R_l0_g2R_l1_g2R2C0R2C1R2C2R2C3R2C4
R_l0_g3R_l1_g3R3C0R3C1R3C2R3C3R3C4
R_l0_g4R_l1_g4R4C0R4C1R4C2R4C3R4C4
R_l0_g5R_l1_g5R5C0R5C1R5C2R5C3R5C4
R_l0_g6R_l1_g6R6C0R6C1R6C2R6C3R6C4
R_l0_g7R_l1_g7R7C0R7C1R7C2R7C3R7C4
R_l0_g8R_l1_g8R8C0R8C1R8C2R8C3R8C4
R_l0_g9R_l1_g9R9C0R9C1R9C2R9C3R9C4
" + ], + "metadata": {}, + "output_type": "pyout", + "prompt_number": 15, + "text": [ + "" + ] + } + ], + "prompt_number": 15 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "# basic latex output, matching to_latex (+ boilerplate)\n", + "latex_s=pd.io.templating.Styler(df,template=open(\"/home/user1/src/pandas/pandas/io/templating/templates/latex\").read())\n", + "print latex_s.render()" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "\n", + "\\documentclass[11pt,a4paper]{article}\n", + "\\usepackage{booktabs}\n", + "\n", + "\\begin{document}\n", + "\n", + "\\begin{tabular}{ lllllll }\n", + "\n", + "\\toprule\n", + " \n", + " & & C_l0_g0 & C_l0_g1 & C_l0_g2 & C_l0_g3 & C_l0_g4 \\\\\n", + " & & C_l1_g0 & C_l1_g1 & C_l1_g2 & C_l1_g3 & C_l1_g4 \\\\\n", + " & & C_l2_g0 & C_l2_g1 & C_l2_g2 & C_l2_g3 & C_l2_g4 \\\\\n", + "\n", + "\\midrule\n", + " \n", + " R_l0_g0 & R_l1_g0 & R0C0 & R0C1 & R0C2 & R0C3 & R0C4 \\\\\n", + " R_l0_g1 & R_l1_g1 & R1C0 & R1C1 & R1C2 & R1C3 & R1C4 \\\\\n", + " R_l0_g2 & R_l1_g2 & R2C0 & R2C1 & R2C2 & R2C3 & R2C4 \\\\\n", + " R_l0_g3 & R_l1_g3 & R3C0 & R3C1 & R3C2 & R3C3 & R3C4 \\\\\n", + " R_l0_g4 & R_l1_g4 & R4C0 & R4C1 & R4C2 & R4C3 & R4C4 \\\\\n", + " R_l0_g5 & R_l1_g5 & R5C0 & R5C1 & R5C2 & R5C3 & R5C4 \\\\\n", + " R_l0_g6 & R_l1_g6 & R6C0 & R6C1 & R6C2 & R6C3 & R6C4 \\\\\n", + " R_l0_g7 & R_l1_g7 & R7C0 & R7C1 & R7C2 & R7C3 & R7C4 \\\\\n", + " R_l0_g8 & R_l1_g8 & R8C0 & R8C1 & R8C2 & R8C3 & R8C4 \\\\\n", + " R_l0_g9 & R_l1_g9 & R9C0 & R9C1 & R9C2 & R9C3 & R9C4 \\\\\n", + "\\bottomrule\n", + "\n", + "\\end{tabular}\n", + "\n", + "\\end{document}\n" + ] + } + ], + "prompt_number": 10 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "# markdown, just to try out the machinery\n", + "# Works with GH GFM\n", + "df=mkdf(10,5,r_idx_nlevels=2)\n", + "md_s=pd.io.templating.Styler(df,template=open(\"/home/user1/src/pandas/pandas/io/templating/templates/markdown\").read())\n", + "print md_s.render()\n" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "\n", + "\n", + "| | |__C_l0_g0__ |__C_l0_g1__ |__C_l0_g2__ |__C_l0_g3__ |__C_l0_g4__ |\n", + "| --- | --- | --- | --- | --- | --- | --- | \n", + "|__R_l0_g0__ |__R_l1_g0__ |R0C0 |R0C1 |R0C2 |R0C3 |R0C4 |\n", + "|__R_l0_g1__ |__R_l1_g1__ |R1C0 |R1C1 |R1C2 |R1C3 |R1C4 |\n", + "|__R_l0_g2__ |__R_l1_g2__ |R2C0 |R2C1 |R2C2 |R2C3 |R2C4 |\n", + "|__R_l0_g3__ |__R_l1_g3__ |R3C0 |R3C1 |R3C2 |R3C3 |R3C4 |\n", + "|__R_l0_g4__ |__R_l1_g4__ |R4C0 |R4C1 |R4C2 |R4C3 |R4C4 |\n", + "|__R_l0_g5__ |__R_l1_g5__ |R5C0 |R5C1 |R5C2 |R5C3 |R5C4 |\n", + "|__R_l0_g6__ |__R_l1_g6__ |R6C0 |R6C1 |R6C2 |R6C3 |R6C4 |\n", + "|__R_l0_g7__ |__R_l1_g7__ |R7C0 |R7C1 |R7C2 |R7C3 |R7C4 |\n", + "|__R_l0_g8__ |__R_l1_g8__ |R8C0 |R8C1 |R8C2 |R8C3 |R8C4 |\n", + "|__R_l0_g9__ |__R_l1_g9__ |R9C0 |R9C1 |R9C2 |R9C3 |R9C4 |\n" + ] + } + ], + "prompt_number": 13 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [], + "language": "python", + "metadata": {}, + "outputs": [] + } + ], + "metadata": {} + } + ] +} \ No newline at end of file diff --git a/setup.py b/setup.py index fe921b1ff6029..5e70529ccde0e 100755 --- a/setup.py +++ b/setup.py @@ -535,6 +535,7 @@ def pxd(name): 'pandas.computation.tests', 'pandas.core', 'pandas.io', + 'pandas.io.templating', 'pandas.rpy', 'pandas.sandbox', 'pandas.sparse',