Skip to content

Commit 0459008

Browse files
committed
ENH: add a functional funtional line
Also set up sphinx gallery
1 parent 7df098b commit 0459008

File tree

7 files changed

+168
-4
lines changed

7 files changed

+168
-4
lines changed

.gitignore

+20
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,23 @@ target/
8080

8181
#Ipython Notebook
8282
.ipynb_checkpoints
83+
84+
85+
# Documentation generated files #
86+
#################################
87+
# sphinx build directory
88+
docs/_build
89+
docs/source/api/_as_gen
90+
# autogenerated by sphinx-gallery
91+
docs/source/gallery/
92+
lib/dateutil
93+
examples/*/*.bmp
94+
examples/*/*.eps
95+
examples/*/*.pdf
96+
examples/*/*.png
97+
examples/*/*.svg
98+
examples/*/*.svgz
99+
examples/tests/*
100+
!examples/tests/backend_driver_sgskip.py
101+
result_images
102+
doc/_static/constrained_layout*.png

data_prototype/containers.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import numpy as np
2+
3+
4+
class DataContainer:
5+
def query(self, data_bounds, size, xscale=None, yscale=None):
6+
raise NotImplementedError
7+
8+
9+
class ArrayContainer:
10+
def __init__(self, **data):
11+
self._data = data
12+
13+
def query(self, data_bounds, size, xscale=None, yscale=None):
14+
return dict(self._data)
15+
16+
17+
class FuncContainer:
18+
def __init__(self, xfuncs, yfuncs=None, xyfuncs=None):
19+
self._xfuncs = xfuncs or {}
20+
self._yfuncs = yfuncs or {}
21+
self._xyfuncs = xyfuncs or {}
22+
23+
def query(self, data_bounds, size, xscale=None, yscale=None):
24+
xmin, xmax, ymin, ymax = data_bounds
25+
xpix, ypix = size
26+
x_data = np.linspace(xmin, xmax, int(xpix) * 2)
27+
y_data = np.linspace(ymin, ymax, int(ypix) * 2)
28+
return dict(
29+
**{k: f(x_data) for k, f in self._xfuncs.items()},
30+
**{k: f(y_data) for k, f in self._yfuncs.items()},
31+
**{k: f(x_data, y_data) for k, f in self._xyfuncs.items()}
32+
)

data_prototype/wrappers.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from matplotlib.lines import Line2D as _Line2D
2+
3+
4+
class ProxyWrapper:
5+
_privtized_methods = ()
6+
_wrapped_class = None
7+
_wrapped_instance = None
8+
9+
def draw(self, renderer):
10+
raise NotImplementedError
11+
12+
def __getattr__(self, key):
13+
if key in self._privtized_methods:
14+
raise AttributeError(f"The method {key} has been privitized")
15+
if key[0] == "_" and key[1:] in self._privtized_methods:
16+
return getattr(self._wrapped_instance, key[1:])
17+
return getattr(self._wrapped_instance, key)
18+
19+
def __setattr__(self, key, value):
20+
if hasattr(self._wrapped_instance, key):
21+
setattr(self._wrapped_instance, key, value)
22+
else:
23+
super().__setattr__(key, value)
24+
25+
26+
class LineWrapper(ProxyWrapper):
27+
_wrapped_class = _Line2D
28+
_privtized_methods = set(["set_xdata", "set_ydata", "set_data"])
29+
30+
def __init__(self, data, /, **kwargs):
31+
self._wrapped_instance = self._wrapped_class([], [], **kwargs)
32+
self.data = data
33+
34+
def draw(self, renderer):
35+
ax = self._wrapped_instance.axes
36+
ax_bbox = ax.get_window_extent(renderer)
37+
data = self.data.query([*ax.get_xlim(), *ax.get_ylim()], ax_bbox.size)
38+
self._wrapped_instance.set_data(data["x"], data["y"])
39+
return self._wrapped_instance.draw(renderer)

docs/source/conf.py

+50-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
# add these directories to sys.path here. If the directory is relative to the
1818
# documentation root, use os.path.abspath to make it absolute, like shown here.
1919
#
20-
# import os
20+
import os
2121
# import sys
2222
# sys.path.insert(0, os.path.abspath('.'))
23+
from pathlib import Path
2324

25+
# are we running circle CI?
26+
CIRCLECI = 'CIRCLECI' in os.environ
2427

2528
# -- General configuration ------------------------------------------------
2629

@@ -43,17 +46,61 @@
4346
'matplotlib.sphinxext.plot_directive',
4447
'numpydoc',
4548
'sphinx_copybutton',
49+
'sphinx_gallery.gen_gallery',
4650
]
4751

4852
# Configuration options for plot_directive. See:
4953
# https://github.com/matplotlib/matplotlib/blob/f3ed922d935751e08494e5fb5311d3050a3b637b/lib/matplotlib/sphinxext/plot_directive.py#L81
5054
plot_html_show_source_link = False
5155
plot_html_show_formats = False
5256

57+
5358
# Generate the API documentation when building
5459
autosummary_generate = True
5560
numpydoc_show_class_members = False
5661

62+
is_release_build = False
63+
64+
# Sphinx gallery configuration
65+
66+
def matplotlib_reduced_latex_scraper(block, block_vars, gallery_conf,
67+
**kwargs):
68+
"""
69+
Reduce srcset when creating a PDF.
70+
71+
Because sphinx-gallery runs *very* early, we cannot modify this even in the
72+
earliest builder-inited signal. Thus we do it at scraping time.
73+
"""
74+
from sphinx_gallery.scrapers import matplotlib_scraper
75+
76+
if gallery_conf['builder_name'] == 'latex':
77+
gallery_conf['image_srcset'] = []
78+
return matplotlib_scraper(block, block_vars, gallery_conf, **kwargs)
79+
80+
81+
sphinx_gallery_conf = {
82+
'examples_dirs': ['../../examples', ],
83+
'filename_pattern': '^((?!sgskip).)*$',
84+
'gallery_dirs': ['gallery'],
85+
'doc_module': ('data_prototype',),
86+
'reference_url': {
87+
'matplotlib': None,
88+
},
89+
'backreferences_dir': Path('api') / Path('_as_gen'),
90+
'remove_config_comments': True,
91+
'min_reported_time': 1,
92+
'thumbnail_size': (320, 224),
93+
'image_scrapers': (matplotlib_reduced_latex_scraper, ),
94+
# Compression is a significant effort that we skip for local and CI builds.
95+
'compress_images': ('thumbnails', 'images') if is_release_build else (),
96+
'matplotlib_animations': True,
97+
'image_srcset': ["2x"],
98+
'junit': '../test-results/sphinx-gallery/junit.xml' if CIRCLECI else '',
99+
}
100+
101+
mathmpl_fontsize = 11.0
102+
mathmpl_srcset = ['2x']
103+
57104
# Add any paths that contain templates here, relative to this directory.
58105
templates_path = ['_templates']
59106

@@ -105,9 +152,8 @@
105152
# The theme to use for HTML and HTML Help pages. See the documentation for
106153
# a list of builtin themes.
107154
#
108-
html_theme = 'sphinx_rtd_theme'
109-
import sphinx_rtd_theme
110-
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
155+
html_theme = "mpl_sphinx_theme"
156+
111157

112158
# Theme options are theme-specific and customize the look and feel of a theme
113159
# further. For a list of options available for each theme, see the

docs/source/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ data_prototype Documentation
1111

1212
installation
1313
usage
14+
gallery/index.rst
1415
release-history
1516
min_versions

examples/README.rst

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
========
2+
Examples
3+
========
4+
5+
Examples used in the rapid prototyping of this project.

examples/first.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""
2+
=================
3+
A functional line
4+
=================
5+
6+
The hello-world
7+
"""
8+
9+
import matplotlib.pyplot as plt
10+
import numpy as np
11+
12+
from data_prototype.wrappers import LineWrapper
13+
from data_prototype.containers import FuncContainer
14+
15+
fc = FuncContainer({'x': lambda x: x, 'y': lambda x: np.sin(x)})
16+
lw = LineWrapper(fc, lw=5, color='green')
17+
18+
fig, ax = plt.subplots()
19+
ax.add_artist(lw)
20+
ax.set_xlim(0, np.pi * 2)
21+
ax.set_ylim(-1.1, 1.1)

0 commit comments

Comments
 (0)