pfund-plot 0.0.1__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.
- pfund_plot/__init__.py +183 -0
- pfund_plot/__main__.py +9 -0
- pfund_plot/cli/__init__.py +3 -0
- pfund_plot/cli/commands/gallery/__init__.py +15 -0
- pfund_plot/cli/commands/gallery/gallery_marimo.py +462 -0
- pfund_plot/cli/commands/serve.py +21 -0
- pfund_plot/cli/main.py +20 -0
- pfund_plot/config.py +109 -0
- pfund_plot/enums/__init__.py +16 -0
- pfund_plot/enums/dataframe_backend.py +6 -0
- pfund_plot/enums/display_mode.py +7 -0
- pfund_plot/enums/panel_design.py +8 -0
- pfund_plot/enums/panel_theme.py +6 -0
- pfund_plot/enums/plotting_backend.py +12 -0
- pfund_plot/js_tap/components/candlestick.js +9566 -0
- pfund_plot/mixins/streaming_market_feed_mixin.py +162 -0
- pfund_plot/plots/altair.py +32 -0
- pfund_plot/plots/area/__init__.py +82 -0
- pfund_plot/plots/area/bokeh.py +151 -0
- pfund_plot/plots/bar/__init__.py +80 -0
- pfund_plot/plots/bar/bokeh.py +128 -0
- pfund_plot/plots/bokeh.py +32 -0
- pfund_plot/plots/candlestick/__init__.py +77 -0
- pfund_plot/plots/candlestick/bokeh.py +124 -0
- pfund_plot/plots/candlestick/svelte.py +161 -0
- pfund_plot/plots/holoviews.py +32 -0
- pfund_plot/plots/label/__init__.py +43 -0
- pfund_plot/plots/label/bokeh.py +89 -0
- pfund_plot/plots/layout/__init__.py +98 -0
- pfund_plot/plots/layout/layout.py +116 -0
- pfund_plot/plots/layout/panel.py +51 -0
- pfund_plot/plots/layout/tabs/__init__.py +36 -0
- pfund_plot/plots/layout/tabs/panel.py +51 -0
- pfund_plot/plots/lazy.py +408 -0
- pfund_plot/plots/line/__init__.py +37 -0
- pfund_plot/plots/line/bokeh.py +137 -0
- pfund_plot/plots/matplotlib.py +32 -0
- pfund_plot/plots/plot.py +1131 -0
- pfund_plot/plots/plotly.py +32 -0
- pfund_plot/plots/scatter/__init__.py +62 -0
- pfund_plot/plots/scatter/bokeh.py +158 -0
- pfund_plot/plots/scatter/marker.py +107 -0
- pfund_plot/plots/ta.py +6 -0
- pfund_plot/renderers/base.py +84 -0
- pfund_plot/renderers/browser.py +28 -0
- pfund_plot/renderers/desktop.py +109 -0
- pfund_plot/renderers/notebook.py +92 -0
- pfund_plot/typing.py +29 -0
- pfund_plot/utils/__init__.py +176 -0
- pfund_plot/utils/bokeh.py +177 -0
- pfund_plot/widgets/base.py +76 -0
- pfund_plot/widgets/datetime_widget.py +221 -0
- pfund_plot/widgets/ticker_widget.py +82 -0
- pfund_plot-0.0.1.dist-info/METADATA +148 -0
- pfund_plot-0.0.1.dist-info/RECORD +57 -0
- pfund_plot-0.0.1.dist-info/WHEEL +4 -0
- pfund_plot-0.0.1.dist-info/entry_points.txt +6 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# pyright: reportUnusedParameter=false, reportArgumentType=false
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from holoviews.core.overlay import NdOverlay
|
|
8
|
+
|
|
9
|
+
import narwhals as nw
|
|
10
|
+
|
|
11
|
+
from pfund_plot.enums import PlottingBackend
|
|
12
|
+
|
|
13
|
+
__all__ = ["control", "plot", "style"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
DEFAULT_COLOR = "steelblue"
|
|
17
|
+
DEFAULT_HEIGHT = 280
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def style(
|
|
21
|
+
title: str = "",
|
|
22
|
+
xlabel: str = "",
|
|
23
|
+
ylabel: str = "",
|
|
24
|
+
color: str = DEFAULT_COLOR,
|
|
25
|
+
bg_color: str = "", # empty string by default because Panel will automatically use the theme color
|
|
26
|
+
grid: bool = False,
|
|
27
|
+
total_height: int | None = None,
|
|
28
|
+
height: int = DEFAULT_HEIGHT,
|
|
29
|
+
width: int | None = None,
|
|
30
|
+
):
|
|
31
|
+
"""
|
|
32
|
+
Args:
|
|
33
|
+
title: the title of the plot
|
|
34
|
+
xlabel: the label of the x-axis
|
|
35
|
+
ylabel: the label of the y-axis
|
|
36
|
+
color: the color of the plot, hex code is supported, only used when there is only one line
|
|
37
|
+
bg_color: the background color of the plot, hex code is supported
|
|
38
|
+
total_height: the height of the component (including the figure + widgets)
|
|
39
|
+
Default is None, when it is None, Panel will automatically adjust its height
|
|
40
|
+
height: the height of the figure
|
|
41
|
+
width: the width of the plot, since the plot is responsive, this is only used in panel layout
|
|
42
|
+
grid: whether to show the grid
|
|
43
|
+
"""
|
|
44
|
+
return locals()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def control(
|
|
48
|
+
num_data: int | None = None,
|
|
49
|
+
max_data: int | None = None,
|
|
50
|
+
slider_step: int | None = None,
|
|
51
|
+
widgets: bool = True,
|
|
52
|
+
linked_axes: bool = True,
|
|
53
|
+
update_interval: int = 5000, # ms
|
|
54
|
+
incremental_update: bool = True,
|
|
55
|
+
datetime_precision: Literal["d", "s", "ms"] = "s",
|
|
56
|
+
):
|
|
57
|
+
"""
|
|
58
|
+
Args:
|
|
59
|
+
num_data: (DatetimeRangeWidget) initial number of most recent data points to display.
|
|
60
|
+
max_data: (streaming) maximum number of data points kept in memory.
|
|
61
|
+
If None, data will continue to grow unbounded.
|
|
62
|
+
slider_step: (DatetimeRangeWidget) step size in ms for the datetime range slider.
|
|
63
|
+
If None, derived from data resolution.
|
|
64
|
+
widgets: whether to show widgets. default is True.
|
|
65
|
+
For granular control, use remove_widgets() to remove specific widget classes.
|
|
66
|
+
linked_axes: whether to link axes across plots in a layout (plt.layout(...)).
|
|
67
|
+
incremental_update: (streaming) whether to update even when the bar is incomplete. default is True.
|
|
68
|
+
update_interval: (streaming) interval in ms to update the plot. default is 5000 ms.
|
|
69
|
+
datetime_precision: the precision of datetime formatting on the hover tooltip.
|
|
70
|
+
"d" for days (%Y-%m-%d), "s" for seconds (default, %Y-%m-%d %H:%M:%S), "ms" for milliseconds (%Y-%m-%d %H:%M:%S.%3N).
|
|
71
|
+
"""
|
|
72
|
+
return locals()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def plot(
|
|
76
|
+
df: nw.DataFrame[Any],
|
|
77
|
+
style: dict[str, Any],
|
|
78
|
+
control: dict[str, Any],
|
|
79
|
+
x: str | None = None,
|
|
80
|
+
y: str | list[str] | None = None,
|
|
81
|
+
**kwargs: Any,
|
|
82
|
+
) -> NdOverlay:
|
|
83
|
+
import hvplot
|
|
84
|
+
from bokeh.models import CrosshairTool
|
|
85
|
+
|
|
86
|
+
from pfund_plot.plots.line import Line
|
|
87
|
+
from pfund_plot.utils.bokeh import (
|
|
88
|
+
create_bundled_hover_tool,
|
|
89
|
+
create_vline_hover_opts,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
_ = hvplot.extension(PlottingBackend.bokeh)
|
|
93
|
+
|
|
94
|
+
# resolve y column names
|
|
95
|
+
x_col = x
|
|
96
|
+
y_cols = Line._derive_y_cols(df, x, y)
|
|
97
|
+
datetime_precision = control["datetime_precision"]
|
|
98
|
+
|
|
99
|
+
is_single = len(y_cols) == 1
|
|
100
|
+
crosshair_tool = CrosshairTool(
|
|
101
|
+
dimensions="height", line_color="gray", line_alpha=0.3
|
|
102
|
+
)
|
|
103
|
+
if is_single:
|
|
104
|
+
tools = [
|
|
105
|
+
create_bundled_hover_tool(df, x_col, y_cols, datetime_precision),
|
|
106
|
+
crosshair_tool,
|
|
107
|
+
]
|
|
108
|
+
else:
|
|
109
|
+
tools = [crosshair_tool]
|
|
110
|
+
|
|
111
|
+
if is_single:
|
|
112
|
+
kwargs["color"] = style["color"]
|
|
113
|
+
else:
|
|
114
|
+
kwargs["hover_cols"] = y_cols
|
|
115
|
+
|
|
116
|
+
plot = (
|
|
117
|
+
df.to_native()
|
|
118
|
+
.hvplot.line(
|
|
119
|
+
x=x,
|
|
120
|
+
y=y,
|
|
121
|
+
tools=tools,
|
|
122
|
+
grid=style["grid"],
|
|
123
|
+
bgcolor=style["bg_color"],
|
|
124
|
+
responsive=True,
|
|
125
|
+
**kwargs,
|
|
126
|
+
)
|
|
127
|
+
.opts(
|
|
128
|
+
title=style["title"],
|
|
129
|
+
xlabel=style["xlabel"],
|
|
130
|
+
ylabel=style["ylabel"],
|
|
131
|
+
height=style["height"],
|
|
132
|
+
)
|
|
133
|
+
)
|
|
134
|
+
if not is_single:
|
|
135
|
+
plot = plot.opts(create_vline_hover_opts(df, x_col, y_cols, datetime_precision))
|
|
136
|
+
|
|
137
|
+
return plot
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Literal
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from matplotlib.figure import Figure as MatplotlibFigure
|
|
7
|
+
|
|
8
|
+
from pfund_plot.enums import PlottingBackend
|
|
9
|
+
from pfund_plot.plots.plot import BasePlot
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Matplotlib(BasePlot):
|
|
13
|
+
SUPPORTED_BACKENDS: ClassVar[list[Literal[PlottingBackend.matplotlib]]] = [
|
|
14
|
+
PlottingBackend.matplotlib
|
|
15
|
+
]
|
|
16
|
+
REQUIRED_DATA: ClassVar[bool] = False
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self, fig: MatplotlibFigure, sizing_mode: str | None = None, **pane_kwargs: Any
|
|
20
|
+
):
|
|
21
|
+
"""
|
|
22
|
+
Args:
|
|
23
|
+
fig: A Matplotlib Figure object.
|
|
24
|
+
sizing_mode: Panel sizing mode: e.g. "stretch_width", "stretch_height", or "stretch_both".
|
|
25
|
+
**pane_kwargs: Additional keyword arguments passed to pn.pane.Matplotlib,
|
|
26
|
+
e.g. height, width, max_width, margin.
|
|
27
|
+
"""
|
|
28
|
+
super().__init__(data=None)
|
|
29
|
+
self._plot: MatplotlibFigure = fig
|
|
30
|
+
self._pane_kwargs = pane_kwargs
|
|
31
|
+
if sizing_mode is not None:
|
|
32
|
+
self._pane_kwargs["sizing_mode"] = sizing_mode
|