Skip to content

Commit 5afabc2

Browse files
committed
Initial commit
1 parent 8d68d59 commit 5afabc2

File tree

3 files changed

+121
-25
lines changed

3 files changed

+121
-25
lines changed

docs/api.rst

+34-25
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,23 @@
44
API reference
55
=============
66

7-
The comprehensive API reference. All of the below objects are imported
8-
into the top-level namespace. Use ``help(pplt.object)`` to read
9-
the docs during a python session.
7+
Comprehensive documentation of ProPlot functions and classes. All of these
8+
objects are imported into the top-level namespace, so you can read the
9+
documentation within python sessions using ``help(pplt.function_or_class)``.
10+
Please note that the "wrapper" function documentation from proplot < 0.8
11+
is now located on the individual plotting commands under
12+
`proplot.axes.PlotAxes`. When calling ``help(axes.command)`` on
13+
plotting commands during a python session, both the ProPlot
14+
documentation and the original matplotlib documentation are shown.
15+
16+
Top-level functions
17+
===================
18+
19+
.. automodule:: proplot.ui
20+
21+
.. automodsumm:: proplot.ui
22+
:toctree: api
1023

11-
Please note that the documentation for "wrapper" functions from
12-
proplot < 0.8 is now found under the individual `~proplot.axes.PlotAxes`
13-
plotting commands. Using ``help(ax.command)`` during a python session shows both
14-
the proplot documentation and the original matplotlib documentation.
1524

1625
Figure class
1726
============
@@ -20,16 +29,16 @@ Figure class
2029

2130
.. automodsumm:: proplot.figure
2231
:toctree: api
32+
:skip: SubplotsContainer
2333

2434

25-
Grid classes
26-
============
35+
Gridspec class
36+
==============
2737

2838
.. automodule:: proplot.gridspec
2939

3040
.. automodsumm:: proplot.gridspec
3141
:toctree: api
32-
:skip: SubplotsContainer
3342

3443

3544
Axes classes
@@ -41,15 +50,6 @@ Axes classes
4150
:toctree: api
4251

4352

44-
Top-level functions
45-
===================
46-
47-
.. automodule:: proplot.ui
48-
49-
.. automodsumm:: proplot.ui
50-
:toctree: api
51-
52-
5353
Configuration tools
5454
===================
5555

@@ -107,20 +107,29 @@ Projection classes
107107
:toctree: api
108108

109109

110-
Demo functions
111-
==============
110+
Artist subclass
111+
===============
112112

113-
.. automodule:: proplot.demos
113+
.. automodule:: proplot.artist
114114

115-
.. automodsumm:: proplot.demos
115+
.. automodsumm:: proplot.artist
116116
:toctree: api
117117

118118

119-
Miscellaneous functions
120-
=======================
119+
Miscellaneous tools
120+
===================
121121

122122
.. automodule:: proplot.utils
123123

124124
.. automodsumm:: proplot.utils
125125
:toctree: api
126126
:skip: shade, saturate
127+
128+
129+
Demo functions
130+
==============
131+
132+
.. automodule:: proplot.demos
133+
134+
.. automodsumm:: proplot.demos
135+
:toctree: api

proplot/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
from .ui import * # noqa: F401 F403
5151
with _benchmark('demos'):
5252
from .demos import * # noqa: F401 F403
53+
from .artist import * # noqa: F401 F403
5354

5455
# Dynamically add registered classes to top-level namespace
5556
from .constructor import NORMS, LOCATORS, FORMATTERS, SCALES, PROJS

proplot/artist.py

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Add dot-notation properties for matplotlib setter and getter functions.
4+
"""
5+
import warnings
6+
7+
import matplotlib.artist as martist
8+
from matplotlib import MatplotlibDeprecationWarning
9+
10+
__all__ = []
11+
12+
13+
PROPS_IGNORE = (
14+
# Axes props
15+
'axes',
16+
'figure',
17+
'xaxis', # axes prop
18+
'yaxis', # axes prop
19+
'zaxis', # axes prop
20+
'units', # axis prop
21+
'gridlines',
22+
# Method conflicts
23+
'legend',
24+
'tight_layout',
25+
# Class-level conflicts
26+
'contains',
27+
'zorder',
28+
'pickradius', # line property related to 'contains'
29+
# Instance-level artist conflicts
30+
'label',
31+
'label_position',
32+
# Instance-level axes conflicts
33+
'cmap',
34+
'norm',
35+
'lines',
36+
'images',
37+
'title', # TODO: use internal title handling
38+
)
39+
40+
41+
def _iter_subclasses(cls):
42+
"""
43+
Iterate through all subclasses.
44+
"""
45+
yield cls
46+
try:
47+
for subclass in cls.__subclasses__():
48+
yield from _iter_subclasses(subclass)
49+
except TypeError:
50+
pass
51+
52+
53+
def _add_properties(cls):
54+
"""
55+
Generate property definitions for every artist getter.
56+
"""
57+
for attr in dir(cls):
58+
try:
59+
getter = getattr(cls, attr)
60+
except MatplotlibDeprecationWarning:
61+
continue
62+
if not callable(getter) or attr[:4] != 'get_':
63+
continue
64+
prop = attr[4:]
65+
if prop in PROPS_IGNORE:
66+
continue
67+
if hasattr(cls, prop):
68+
value = getattr(cls, prop)
69+
if not isinstance(value, property): # i.e. this is not child of a class
70+
warnings._warn_proplot(f'Skipping property {prop!r}. Already exists as attribute.') # noqa: E501
71+
continue
72+
args = [getter] # property() function args
73+
setter = getattr(cls, 'set_' + prop, None)
74+
if callable(setter):
75+
args.append(setter)
76+
obj = property(*args, doc=getter.__doc__)
77+
setattr(cls, prop, obj)
78+
79+
80+
# Apply properties
81+
# NOTE: While we can guard against class-level attribute conflicts we *cannot* guard
82+
# against instance-level attribute conflicts. Therefore this may never work.
83+
for cls in _iter_subclasses(martist.Artist):
84+
with warnings.catch_warnings():
85+
warnings.simplefilter('error', MatplotlibDeprecationWarning)
86+
_add_properties(cls)

0 commit comments

Comments
 (0)