Skip to content

Commit 662f747

Browse files
simple theme helpers for 8 plotting/table packages
1 parent a2a6554 commit 662f747

File tree

2 files changed

+154
-5
lines changed

2 files changed

+154
-5
lines changed

quarto/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,11 @@
66
from quarto.quarto import path
77
from quarto.render import render
88
from quarto.metadata import metadata
9-
from quarto.theme import plotly_theme_colors, plotly_theme_brand
9+
from quarto.theme import theme_colors_altair, theme_brand_altair, \
10+
theme_colors_bokeh, theme_brand_bokeh, \
11+
theme_colors_great_tables, theme_brand_great_tables, \
12+
theme_colors_matplotlib, theme_brand_matplotlib, \
13+
theme_colors_plotnine, theme_brand_plotnine, \
14+
theme_colors_plotly, theme_brand_plotly, \
15+
theme_colors_pygal, theme_brand_pygal, \
16+
theme_colors_seaborn, theme_brand_seaborn

quarto/theme.py

Lines changed: 146 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,156 @@
11
import yaml
2-
import plotly.graph_objects as go
32
from functools import partial
43

5-
def plotly_theme_colors(bg, fg):
4+
def theme_colors_altair(bg, fg):
5+
return {
6+
'config': {
7+
'view': {'stroke': 'transparent'},
8+
'axis': {
9+
'domainColor': fg,
10+
'labelColor': fg,
11+
'titleColor': fg,
12+
},
13+
'legend': {
14+
'labelColor': fg,
15+
'titleColor': fg,
16+
},
17+
'background': bg, # Background color
18+
}
19+
}
20+
21+
def theme_brand_altair(brand_yml):
22+
brand = yaml.safe_load(open(brand_yml).read())
23+
bg = brand["color"]["background"]
24+
fg = brand["color"]["foreground"]
25+
return partial(theme_colors_altair, bg, fg)
26+
27+
# background fill is incomplete
28+
def theme_colors_bokeh(bg, fg):
29+
from bokeh.io import curdoc
30+
from bokeh.themes import Theme
31+
curdoc().theme = Theme(json={'attrs': {
32+
'figure': {
33+
'background_fill_color': bg, # just plot area
34+
},
35+
'Title': {
36+
'background_fill_color': bg,
37+
'text_color': fg,
38+
},
39+
'Axis': {
40+
'background_fill_color': bg,
41+
'axis_label_text_color': fg,
42+
'major_label_text_color': fg,
43+
},
44+
}})
45+
46+
def theme_brand_bokeh(brand_yml):
47+
brand = yaml.safe_load(open(brand_yml).read())
48+
fg = brand["color"]["foreground"]
49+
bg = brand["color"]["background"]
50+
return partial(theme_colors_bokeh, bg, fg)
51+
52+
53+
def theme_colors_great_tables(bg, fg):
54+
return {
55+
'table_background_color': bg,
56+
'table_font_color': fg
57+
}
58+
def theme_brand_great_tables(brand_yml):
59+
brand = yaml.safe_load(open(brand_yml).read())
60+
fg = brand["color"]["foreground"]
61+
bg = brand["color"]["background"]
62+
return theme_colors_great_tables(bg, fg)
63+
64+
65+
def theme_colors_matplotlib(bg, fg, primary):
66+
import matplotlib as mpl
67+
from cycler import cycler
68+
mpl.rcParams["axes.facecolor"] = bg
69+
mpl.rcParams["axes.edgecolor"] = fg
70+
mpl.rcParams["axes.labelcolor"] = fg
71+
mpl.rcParams["axes.titlecolor"] = fg
72+
mpl.rcParams["figure.facecolor"] = bg
73+
mpl.rcParams["figure.edgecolor"] = fg
74+
mpl.rcParams["text.color"] = fg
75+
mpl.rcParams["xtick.color"] = fg
76+
mpl.rcParams["ytick.color"] = fg
77+
if primary:
78+
mpl.rcParams["axes.prop_cycle"] = cycler('color', [primary])
79+
80+
81+
def theme_brand_matplotlib(brand_yml):
82+
brand = yaml.safe_load(open(brand_yml).read())
83+
return partial(
84+
theme_colors_matplotlib,
85+
brand["color"]["background"],
86+
brand["color"]["foreground"],
87+
brand["color"]["primary"],
88+
)
89+
90+
91+
def theme_colors_plotnine(bg, fg):
92+
from plotnine import theme, element_rect, element_text
93+
return theme(
94+
plot_background=element_rect(fill=bg, size=0),
95+
text=element_text(color=fg)
96+
)
97+
98+
def theme_brand_plotnine(brand_yml):
99+
brand = yaml.safe_load(open(brand_yml).read())
100+
return theme_colors_plotnine(brand["color"]["background"], brand["color"]["foreground"])
101+
102+
103+
def theme_colors_plotly(bg, fg):
104+
import plotly.graph_objects as go
6105
return go.layout.Template({'layout': {
7106
'paper_bgcolor': bg,
8107
'plot_bgcolor': bg,
9108
'font_color': fg,
10109
}})
11110

12-
def plotly_theme_brand(brand_yml):
111+
def theme_brand_plotly(brand_yml):
13112
brand = yaml.safe_load(open(brand_yml).read())
14-
return plotly_theme_colors(brand["color"]["background"], brand["color"]["foreground"])
113+
return theme_colors_plotly(brand["color"]["background"], brand["color"]["foreground"])
114+
115+
116+
def theme_colors_pygal(_bg, fg, primary, secondary):
117+
from pygal.style import Style
118+
return Style(
119+
background='transparent',
120+
plot_background='transparent',
121+
foreground=fg,
122+
foreground_strong=primary,
123+
foreground_subtle=secondary or '#630C0D',
124+
opacity='.6',
125+
opacity_hover='.9',
126+
transition='400ms ease-in',
127+
colors=('#E853A0', '#E8537A', '#E95355', '#E87653', '#E89B53'))
128+
129+
def theme_brand_pygal(brand_yml):
130+
brand = yaml.safe_load(open(brand_yml).read())
131+
return theme_colors_pygal(
132+
brand["color"]["background"],
133+
brand["color"]["foreground"],
134+
brand["color"]["primary"],
135+
brand["color"].get("secondary"),
136+
)
137+
138+
139+
def theme_colors_seaborn(bg, fg):
140+
# seaborn accepts matplotlib rcparams
141+
return {
142+
"axes.facecolor": bg,
143+
"axes.edgecolor": fg,
144+
"axes.labelcolor": fg,
145+
"axes.titlecolor": fg,
146+
"figure.facecolor": bg,
147+
"figure.edgecolor": fg,
148+
"text.color": fg,
149+
"xtick.color": fg,
150+
"ytick.color": fg,
151+
"grid.color": fg,
152+
}
153+
154+
def theme_brand_seaborn(brand_yml):
155+
brand = yaml.safe_load(open(brand_yml).read())
156+
return theme_colors_seaborn(brand["color"]["background"], brand["color"]["foreground"])

0 commit comments

Comments
 (0)