Как расширить базовый шаблон Pandas Styler

#pandas #jinja2 #pandas-styles

#pandas #jinja2 #pandas-стили

Вопрос:

Привет, я работаю над написанием пользовательского шаблона jinja, который наследуется от Pandas базового шаблона.

Мой шаблон по умолчанию выглядит так

 {% extends "html.tpl" %}
{% block table %}
<style  type="text/css" >
{% block default_table_styles %}
         #T_{{uuid}} th {
          font-size: 100%;
          text-align: center;
          background-color: blue;
          color: white;
          border: black solid thin;
    }    #T_{{uuid}} td {
          font-size: 100%;
          text-align: center;
          background-color: white;
          color: black;
          border: black solid thin;
    }    #T_{{uuid}} th:empty {
          border-width: 0;
    }
{% endblock default_table_styles %}
</style>
{{ super() }}
{% endblock table %}
  

Теперь я создаю макет фрейма данных и пытаюсь выполнить рендеринг с использованием моего пользовательского шаблона, но эффекты не выполняются.

Мой макет кода для фрейма данных

 import numpy as np
import pandas as pd
from pandas.io.formats.style import Styler
from IPython.display import HTML
from bs4 import BeautifulSoup as bs
# make complex dataframe
def mklbl(prefix, n):
        return ["%s%s" % (prefix, i) for i in range(n)]
micolumns = pd.MultiIndex.from_tuples([('a', 'foo'), ('a', 'bar'),
                                           ('b', 'foo'), ('b', 'bah')],
                                          names=['lvl0', 'lvl1'])
miindex = pd.MultiIndex.from_product([mklbl('A', 4),
                                      mklbl('B', 2),
                                      mklbl('C', 4),
                                      mklbl('D', 2)], names=['lvl2','lvl3','lvl4','lvl5'])
df = pd.DataFrame(np.arange(len(miindex) * len(micolumns))
                          .reshape((len(miindex), len(micolumns))),
                        index=miindex,
                        columns=micolumns).sort_index().sort_index(axis=1)
df
  

введите описание изображения здесь

Создание моего пользовательского Styler объекта подкласса с использованием Pandas функции фабрики подклассов.

 EasyStyler = Styler.from_custom_template("path_to_new_tpl_file", "default.tpl")
  

Теперь я визуализирую

 EasyStyler(df)
  

введите описание изображения здесь

Это должно работать в соответствии с моими исследованиями, но, похоже, этого не происходит.

Я попробовал довольно печатать html, и похоже, что мой блок стилей вообще отсутствует.

 print(bs(EasyStyler(df).render()).prettify())
  

введите описание изображения здесь

Я хочу, чтобы пользователи могли переопределять свойства моего шаблона по умолчанию, если они того пожелают. Я думал, что если я включу свой блок стилей перед любым из их кода, то, если пользователь решит переопределить некоторые атрибуты стиля, они будут иметь приоритет над моими, поскольку они появятся позже.

Редактировать:

Итак, я смог получить то, что хочу, переместив style контейнер внутри блока таблицы. Однако сейчас я не могу переопределить эти настройки.

 s = EasyStyler(df)
s.set_table_styles(dict(selector="th", props=[('background-color','red'),('color','white')]))
  

Я надеялся, что приведенное выше изменит цвет фона в th заголовке, но это не так. Я хотел бы знать, как заставить это работать.

введите описание изображения здесь

Правка2:

Похоже, что style контейнер родительских шаблонов помещается перед дочерними элементами, в результате чего дочерние элементы перезаписывают родителей. Есть ли способ заставить их другим способом?

введите описание изображения здесь

Ответ №1:

Итак, после долгого чтения я обнаружил проблему.

Две вещи, которые я узнал, поскольку я никогда раньше не работал с css / html, не говоря уже о шаблонах jinja2.

Если вы посмотрите на шаблон, который Pandas предоставляет, вы увидите, что у них есть пустые блоки, такие как before_style , и before_table если вы вызываете их в своем дочернем шаблоне, который наследуется от него, код, который вы помещаете в эти блоки, выполняется в этом месте.

Вторая ошибка, которую я допустил, заключалась в том, что когда я пытался применить css к таблице. Я не понимал, что, поскольку таблица является основным элементом, мне нужна только таблица id , а не само слово table .

Эти две настройки полностью дали мне то, что я хотел, и шаблон по-прежнему полностью переопределяется из pandas.io.formats.style.Style подкласса.

 {% extends "html.tpl" %}
{%- block before_style -%}
<style  type="text/css">
         #T_{{uuid}} th {
          font-size: 100%;
          text-align: center;
          background-color: blue;
          color: white;
          border: black solid thin;
    }    #T_{{uuid}} td {
          font-size: 100%;
          text-align: center;
          background-color: white;
          color: black;
          border: black solid thin;
    }    #T_{{uuid}} th:empty {
          border-width: 0;
    }
</style>
{%- endblock before_style -%}
{%- block before_table -%}
<style>
         #T_{{uuid}} {
          border: black solid thin;
    }
</style>
{%- endblock before_table -%}
{% block table %}
{{ super() }}
{% endblock table %}