matplotly 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- matplotly/__init__.py +124 -0
- matplotly/_api.py +984 -0
- matplotly/_code_gen.py +1793 -0
- matplotly/_commands.py +109 -0
- matplotly/_introspect.py +1197 -0
- matplotly/_profiles.py +241 -0
- matplotly/_renderer.py +79 -0
- matplotly/_style_import.py +155 -0
- matplotly/_types.py +31 -0
- matplotly/panels/__init__.py +37 -0
- matplotly/panels/_bar.py +788 -0
- matplotly/panels/_base.py +38 -0
- matplotly/panels/_color_utils.py +221 -0
- matplotly/panels/_distribution.py +1605 -0
- matplotly/panels/_errorbar.py +652 -0
- matplotly/panels/_fill.py +90 -0
- matplotly/panels/_global.py +1507 -0
- matplotly/panels/_heatmap.py +898 -0
- matplotly/panels/_histogram.py +938 -0
- matplotly/panels/_line.py +709 -0
- matplotly/panels/_marginal.py +944 -0
- matplotly/panels/_scatter.py +428 -0
- matplotly/panels/_subplot.py +846 -0
- matplotly-0.1.0.dist-info/METADATA +120 -0
- matplotly-0.1.0.dist-info/RECORD +27 -0
- matplotly-0.1.0.dist-info/WHEEL +4 -0
- matplotly-0.1.0.dist-info/licenses/LICENSE +21 -0
matplotly/__init__.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""matplotly — Inline Jupyter matplotlib figure editor.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
# Pass a figure directly
|
|
5
|
+
fig, ax = plt.subplots()
|
|
6
|
+
ax.plot(x, y)
|
|
7
|
+
matplotly(fig)
|
|
8
|
+
|
|
9
|
+
# Decorator
|
|
10
|
+
@matplotly
|
|
11
|
+
def my_plot():
|
|
12
|
+
plt.plot(x, y)
|
|
13
|
+
|
|
14
|
+
# Context manager
|
|
15
|
+
with matplotly() as pb:
|
|
16
|
+
fig, ax = plt.subplots()
|
|
17
|
+
ax.plot(x, y)
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
__version__ = "0.1.0"
|
|
22
|
+
__all__ = ["matplotly"]
|
|
23
|
+
|
|
24
|
+
import functools
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
import matplotlib.pyplot as plt
|
|
28
|
+
from matplotlib.figure import Figure
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _suppress_auto_display(fig: Figure) -> None:
|
|
32
|
+
"""Hide the ipympl auto-displayed canvas and remove from figure manager."""
|
|
33
|
+
# Remove from pyplot's figure manager so ipympl stops tracking it
|
|
34
|
+
try:
|
|
35
|
+
import matplotlib._pylab_helpers as _helpers
|
|
36
|
+
_helpers.Gcf.figs.pop(fig.number, None)
|
|
37
|
+
except Exception:
|
|
38
|
+
pass
|
|
39
|
+
# Hide the auto-displayed ipympl canvas widget (if ipympl is active,
|
|
40
|
+
# fig.canvas is an ipywidget that was already displayed by plt.subplots)
|
|
41
|
+
try:
|
|
42
|
+
fig.canvas.layout.display = 'none'
|
|
43
|
+
fig.canvas.layout.height = '0px'
|
|
44
|
+
except (AttributeError, Exception):
|
|
45
|
+
pass
|
|
46
|
+
# Clear any already-rendered static output from the cell
|
|
47
|
+
try:
|
|
48
|
+
from IPython.display import clear_output
|
|
49
|
+
clear_output(wait=False)
|
|
50
|
+
except Exception:
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class _PlotBuildContext:
|
|
55
|
+
"""Context manager that captures the current figure on exit."""
|
|
56
|
+
|
|
57
|
+
def __enter__(self):
|
|
58
|
+
return self
|
|
59
|
+
|
|
60
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
61
|
+
if exc_type is not None:
|
|
62
|
+
return False
|
|
63
|
+
from ._api import PlotBuildSession
|
|
64
|
+
fig = plt.gcf()
|
|
65
|
+
_suppress_auto_display(fig)
|
|
66
|
+
session = PlotBuildSession(fig)
|
|
67
|
+
session.display()
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _capture_cell_source() -> str | None:
|
|
72
|
+
"""Grab the source of the currently executing Jupyter cell."""
|
|
73
|
+
try:
|
|
74
|
+
from IPython import get_ipython
|
|
75
|
+
ip = get_ipython()
|
|
76
|
+
if ip is not None:
|
|
77
|
+
# In[] list holds all executed cell sources; last entry is current
|
|
78
|
+
in_list = ip.user_ns.get("In")
|
|
79
|
+
if in_list and len(in_list) > 0:
|
|
80
|
+
return in_list[-1]
|
|
81
|
+
except Exception:
|
|
82
|
+
pass
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def matplotly(target: Figure | Any | None = None):
|
|
87
|
+
"""Interactive matplotlib figure editor.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
target : Figure, callable, or None
|
|
92
|
+
- Figure: opens the editor on that figure immediately.
|
|
93
|
+
- callable: decorator mode — calls the function, captures plt.gcf(),
|
|
94
|
+
and opens the editor.
|
|
95
|
+
- None: returns a context manager.
|
|
96
|
+
"""
|
|
97
|
+
from ._api import PlotBuildSession
|
|
98
|
+
|
|
99
|
+
cell_source = _capture_cell_source()
|
|
100
|
+
|
|
101
|
+
# Case 1: Figure passed directly
|
|
102
|
+
if isinstance(target, Figure):
|
|
103
|
+
_suppress_auto_display(target)
|
|
104
|
+
session = PlotBuildSession(target, cell_source=cell_source)
|
|
105
|
+
session.display()
|
|
106
|
+
return None # suppress Jupyter auto-display of return value
|
|
107
|
+
|
|
108
|
+
# Case 2: Callable — decorator mode
|
|
109
|
+
if callable(target):
|
|
110
|
+
@functools.wraps(target)
|
|
111
|
+
def wrapper(*args, **kwargs):
|
|
112
|
+
target(*args, **kwargs)
|
|
113
|
+
fig = plt.gcf()
|
|
114
|
+
_suppress_auto_display(fig)
|
|
115
|
+
cs = _capture_cell_source()
|
|
116
|
+
session = PlotBuildSession(fig, cell_source=cs)
|
|
117
|
+
session.display()
|
|
118
|
+
return wrapper
|
|
119
|
+
|
|
120
|
+
# Case 3: None — context manager mode
|
|
121
|
+
if target is None:
|
|
122
|
+
return _PlotBuildContext()
|
|
123
|
+
|
|
124
|
+
raise TypeError(f"matplotly() expects a Figure, callable, or None, got {type(target)}")
|