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.
Files changed (57) hide show
  1. pfund_plot/__init__.py +183 -0
  2. pfund_plot/__main__.py +9 -0
  3. pfund_plot/cli/__init__.py +3 -0
  4. pfund_plot/cli/commands/gallery/__init__.py +15 -0
  5. pfund_plot/cli/commands/gallery/gallery_marimo.py +462 -0
  6. pfund_plot/cli/commands/serve.py +21 -0
  7. pfund_plot/cli/main.py +20 -0
  8. pfund_plot/config.py +109 -0
  9. pfund_plot/enums/__init__.py +16 -0
  10. pfund_plot/enums/dataframe_backend.py +6 -0
  11. pfund_plot/enums/display_mode.py +7 -0
  12. pfund_plot/enums/panel_design.py +8 -0
  13. pfund_plot/enums/panel_theme.py +6 -0
  14. pfund_plot/enums/plotting_backend.py +12 -0
  15. pfund_plot/js_tap/components/candlestick.js +9566 -0
  16. pfund_plot/mixins/streaming_market_feed_mixin.py +162 -0
  17. pfund_plot/plots/altair.py +32 -0
  18. pfund_plot/plots/area/__init__.py +82 -0
  19. pfund_plot/plots/area/bokeh.py +151 -0
  20. pfund_plot/plots/bar/__init__.py +80 -0
  21. pfund_plot/plots/bar/bokeh.py +128 -0
  22. pfund_plot/plots/bokeh.py +32 -0
  23. pfund_plot/plots/candlestick/__init__.py +77 -0
  24. pfund_plot/plots/candlestick/bokeh.py +124 -0
  25. pfund_plot/plots/candlestick/svelte.py +161 -0
  26. pfund_plot/plots/holoviews.py +32 -0
  27. pfund_plot/plots/label/__init__.py +43 -0
  28. pfund_plot/plots/label/bokeh.py +89 -0
  29. pfund_plot/plots/layout/__init__.py +98 -0
  30. pfund_plot/plots/layout/layout.py +116 -0
  31. pfund_plot/plots/layout/panel.py +51 -0
  32. pfund_plot/plots/layout/tabs/__init__.py +36 -0
  33. pfund_plot/plots/layout/tabs/panel.py +51 -0
  34. pfund_plot/plots/lazy.py +408 -0
  35. pfund_plot/plots/line/__init__.py +37 -0
  36. pfund_plot/plots/line/bokeh.py +137 -0
  37. pfund_plot/plots/matplotlib.py +32 -0
  38. pfund_plot/plots/plot.py +1131 -0
  39. pfund_plot/plots/plotly.py +32 -0
  40. pfund_plot/plots/scatter/__init__.py +62 -0
  41. pfund_plot/plots/scatter/bokeh.py +158 -0
  42. pfund_plot/plots/scatter/marker.py +107 -0
  43. pfund_plot/plots/ta.py +6 -0
  44. pfund_plot/renderers/base.py +84 -0
  45. pfund_plot/renderers/browser.py +28 -0
  46. pfund_plot/renderers/desktop.py +109 -0
  47. pfund_plot/renderers/notebook.py +92 -0
  48. pfund_plot/typing.py +29 -0
  49. pfund_plot/utils/__init__.py +176 -0
  50. pfund_plot/utils/bokeh.py +177 -0
  51. pfund_plot/widgets/base.py +76 -0
  52. pfund_plot/widgets/datetime_widget.py +221 -0
  53. pfund_plot/widgets/ticker_widget.py +82 -0
  54. pfund_plot-0.0.1.dist-info/METADATA +148 -0
  55. pfund_plot-0.0.1.dist-info/RECORD +57 -0
  56. pfund_plot-0.0.1.dist-info/WHEEL +4 -0
  57. 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