-
Notifications
You must be signed in to change notification settings - Fork 432
Expand file tree
/
Copy pathsetup.py
More file actions
280 lines (240 loc) · 8.37 KB
/
setup.py
File metadata and controls
280 lines (240 loc) · 8.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# imports
import os
import sys
import types
import json
import base64
# figure size/format
fig_width = {fig_width}
fig_height = {fig_height}
fig_format = '{fig_format}'
fig_dpi = {fig_dpi}
interactivity = '{interactivity}'
is_shiny = {is_shiny}
is_dashboard = {is_dashboard}
plotly_connected = {plotly_connected}
# matplotlib defaults / format
try:
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (fig_width, fig_height)
plt.rcParams['figure.dpi'] = fig_dpi
plt.rcParams['savefig.dpi'] = "figure"
# IPython 7.14 deprecated set_matplotlib_formats from IPython
try:
from matplotlib_inline.backend_inline import set_matplotlib_formats
except ImportError:
# Fall back to deprecated location for older IPython versions
from IPython.display import set_matplotlib_formats
set_matplotlib_formats(fig_format)
except Exception:
pass
# plotly use connected mode
try:
import plotly.io as pio
if plotly_connected:
pio.renderers.default = "notebook_connected"
else:
pio.renderers.default = "notebook"
for template in pio.templates.keys():
pio.templates[template].layout.margin = dict(t=30,r=0,b=0,l=0)
except Exception:
pass
# disable itables paging for dashboards
if is_dashboard:
try:
from itables import options
options.dom = 'fiBrtlp'
options.maxBytes = 1024 * 1024
options.language = dict(info = "Showing _TOTAL_ entries")
options.classes = "display nowrap compact"
options.paging = False
options.searching = True
options.ordering = True
options.info = True
options.lengthChange = False
options.autoWidth = False
options.responsive = True
options.keys = True
options.buttons = []
except Exception:
pass
try:
import altair as alt
# By default, dashboards will have container sized
# vega visualizations which allows them to flow reasonably
theme_sentinel = '_quarto-dashboard-internal'
def make_theme(name):
nonTheme = alt.themes._plugins[name]
def patch_theme(*args, **kwargs):
existingTheme = nonTheme()
if 'height' not in existingTheme:
existingTheme['height'] = 'container'
if 'width' not in existingTheme:
existingTheme['width'] = 'container'
if 'config' not in existingTheme:
existingTheme['config'] = dict()
# Configure the default font sizes
title_font_size = 15
header_font_size = 13
axis_font_size = 12
legend_font_size = 12
mark_font_size = 12
tooltip = False
config = existingTheme['config']
# The Axis
if 'axis' not in config:
config['axis'] = dict()
axis = config['axis']
if 'labelFontSize' not in axis:
axis['labelFontSize'] = axis_font_size
if 'titleFontSize' not in axis:
axis['titleFontSize'] = axis_font_size
# The legend
if 'legend' not in config:
config['legend'] = dict()
legend = config['legend']
if 'labelFontSize' not in legend:
legend['labelFontSize'] = legend_font_size
if 'titleFontSize' not in legend:
legend['titleFontSize'] = legend_font_size
# The header
if 'header' not in config:
config['header'] = dict()
header = config['header']
if 'labelFontSize' not in header:
header['labelFontSize'] = header_font_size
if 'titleFontSize' not in header:
header['titleFontSize'] = header_font_size
# Title
if 'title' not in config:
config['title'] = dict()
title = config['title']
if 'fontSize' not in title:
title['fontSize'] = title_font_size
# Marks
if 'mark' not in config:
config['mark'] = dict()
mark = config['mark']
if 'fontSize' not in mark:
mark['fontSize'] = mark_font_size
# Mark tooltips
if tooltip and 'tooltip' not in mark:
mark['tooltip'] = dict(content="encoding")
return existingTheme
return patch_theme
# We can only do this once per session
if theme_sentinel not in alt.themes.names():
for name in alt.themes.names():
alt.themes.register(name, make_theme(name))
# register a sentinel theme so we only do this once
alt.themes.register(theme_sentinel, make_theme('default'))
alt.themes.enable('default')
except Exception:
pass
# enable pandas latex repr when targeting pdfs
try:
import pandas as pd
if fig_format == 'pdf':
pd.set_option('display.latex.repr', True)
except Exception:
pass
# interactivity
if interactivity:
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = interactivity
# NOTE: the kernel_deps code is repeated in the cleanup.py file
# (we can't easily share this code b/c of the way it is run).
# If you edit this code also edit the same code in cleanup.py!
# output kernel dependencies
kernel_deps = dict()
for module in list(sys.modules.values()):
# Some modules play games with sys.modules (e.g. email/__init__.py
# in the standard library), and occasionally this can cause strange
# failures in getattr. Just ignore anything that's not an ordinary
# module.
if not isinstance(module, types.ModuleType):
continue
path = getattr(module, "__file__", None)
if not path:
continue
if path.endswith(".pyc") or path.endswith(".pyo"):
path = path[:-1]
if not os.path.exists(path):
continue
kernel_deps[path] = os.stat(path).st_mtime
print(json.dumps(kernel_deps))
# set run_path if requested
run_path = '{run_path}'
if run_path:
# hex-decode the path
run_path = base64.b64decode(run_path.encode("utf-8")).decode("utf-8")
os.chdir(run_path)
# reset state
%reset
# shiny
# Checking for shiny by using {is_shiny} directly because we're after the %reset. We don't want
# to set a variable that stays in global scope.
if {is_shiny}:
try:
import htmltools as _htmltools
import ast as _ast
_htmltools.html_dependency_render_mode = "json"
# This decorator will be added to all function definitions
def _display_if_has_repr_html(x):
try:
# IPython 7.14 preferred import
from IPython.display import display, HTML
except:
from IPython.core.display import display, HTML
if hasattr(x, '_repr_html_'):
display(HTML(x._repr_html_()))
return x
# ideally we would undo the call to ast_transformers.append
# at the end of this block whenver an error occurs, we do
# this for now as it will only be a problem if the user
# switches from shiny to not-shiny mode (and even then likely
# won't matter)
import builtins
builtins._display_if_has_repr_html = _display_if_has_repr_html
class _FunctionDefReprHtml(_ast.NodeTransformer):
def visit_FunctionDef(self, node):
node.decorator_list.insert(
0,
_ast.Name(id="_display_if_has_repr_html", ctx=_ast.Load())
)
return node
def visit_AsyncFunctionDef(self, node):
node.decorator_list.insert(
0,
_ast.Name(id="_display_if_has_repr_html", ctx=_ast.Load())
)
return node
ip = get_ipython()
ip.ast_transformers.append(_FunctionDefReprHtml())
except:
pass
def ojs_define(**kwargs):
import json
try:
# IPython 7.14 preferred import
from IPython.display import display, HTML
except:
from IPython.core.display import display, HTML
# do some minor magic for convenience when handling pandas
# dataframes
def convert(v):
try:
import pandas as pd
except ModuleNotFoundError: # don't do the magic when pandas is not available
return v
if type(v) == pd.Series:
v = pd.DataFrame(v)
if type(v) == pd.DataFrame:
j = json.loads(v.T.to_json(orient='split'))
return dict((k,v) for (k,v) in zip(j["index"], j["data"]))
else:
return v
v = dict(contents=list(dict(name=key, value=convert(value)) for (key, value) in kwargs.items()))
display(HTML('<script type="ojs-define">' + json.dumps(v) + '</script>'), metadata=dict(ojs_define = True))
globals()["ojs_define"] = ojs_define
globals()["__spec__"] = None