pfund-plot 0.0.1.dev3__tar.gz → 0.0.3__tar.gz

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 (109) hide show
  1. pfund_plot-0.0.3/PKG-INFO +146 -0
  2. pfund_plot-0.0.3/README.md +97 -0
  3. pfund_plot-0.0.3/pyproject.toml +85 -0
  4. pfund_plot-0.0.3/src/pfund_plot/__init__.py +178 -0
  5. pfund_plot-0.0.3/src/pfund_plot/__main__.py +9 -0
  6. {pfund_plot-0.0.1.dev3 → pfund_plot-0.0.3/src}/pfund_plot/cli/__init__.py +1 -2
  7. pfund_plot-0.0.3/src/pfund_plot/cli/commands/gallery/__init__.py +15 -0
  8. pfund_plot-0.0.3/src/pfund_plot/cli/commands/gallery/gallery_marimo.py +477 -0
  9. pfund_plot-0.0.3/src/pfund_plot/cli/commands/serve.py +21 -0
  10. pfund_plot-0.0.3/src/pfund_plot/cli/main.py +20 -0
  11. pfund_plot-0.0.3/src/pfund_plot/config.py +97 -0
  12. pfund_plot-0.0.3/src/pfund_plot/enums/__init__.py +16 -0
  13. {pfund_plot-0.0.1.dev3/pfund_plot/const → pfund_plot-0.0.3/src/pfund_plot}/enums/dataframe_backend.py +2 -2
  14. {pfund_plot-0.0.1.dev3/pfund_plot/const → pfund_plot-0.0.3/src/pfund_plot}/enums/display_mode.py +1 -1
  15. pfund_plot-0.0.3/src/pfund_plot/enums/panel_design.py +8 -0
  16. pfund_plot-0.0.3/src/pfund_plot/enums/panel_theme.py +6 -0
  17. pfund_plot-0.0.3/src/pfund_plot/enums/plotting_backend.py +12 -0
  18. pfund_plot-0.0.3/src/pfund_plot/js_tap/components/candlestick.js +9566 -0
  19. pfund_plot-0.0.3/src/pfund_plot/mixins/streaming_market_feed_mixin.py +162 -0
  20. pfund_plot-0.0.3/src/pfund_plot/plots/altair.py +32 -0
  21. pfund_plot-0.0.3/src/pfund_plot/plots/area/__init__.py +82 -0
  22. pfund_plot-0.0.3/src/pfund_plot/plots/area/bokeh.py +151 -0
  23. pfund_plot-0.0.3/src/pfund_plot/plots/bar/__init__.py +80 -0
  24. pfund_plot-0.0.3/src/pfund_plot/plots/bar/bokeh.py +128 -0
  25. pfund_plot-0.0.3/src/pfund_plot/plots/bokeh.py +32 -0
  26. pfund_plot-0.0.3/src/pfund_plot/plots/candlestick/__init__.py +77 -0
  27. pfund_plot-0.0.3/src/pfund_plot/plots/candlestick/bokeh.py +124 -0
  28. pfund_plot-0.0.3/src/pfund_plot/plots/candlestick/svelte.py +163 -0
  29. pfund_plot-0.0.3/src/pfund_plot/plots/holoviews.py +32 -0
  30. pfund_plot-0.0.3/src/pfund_plot/plots/label/__init__.py +43 -0
  31. pfund_plot-0.0.3/src/pfund_plot/plots/label/bokeh.py +89 -0
  32. pfund_plot-0.0.3/src/pfund_plot/plots/layout/__init__.py +98 -0
  33. pfund_plot-0.0.3/src/pfund_plot/plots/layout/layout.py +116 -0
  34. pfund_plot-0.0.3/src/pfund_plot/plots/layout/panel.py +51 -0
  35. pfund_plot-0.0.3/src/pfund_plot/plots/layout/tabs/__init__.py +36 -0
  36. pfund_plot-0.0.3/src/pfund_plot/plots/layout/tabs/panel.py +51 -0
  37. pfund_plot-0.0.3/src/pfund_plot/plots/lazy.py +408 -0
  38. pfund_plot-0.0.3/src/pfund_plot/plots/line/__init__.py +37 -0
  39. pfund_plot-0.0.3/src/pfund_plot/plots/line/bokeh.py +137 -0
  40. pfund_plot-0.0.3/src/pfund_plot/plots/matplotlib.py +32 -0
  41. pfund_plot-0.0.3/src/pfund_plot/plots/plot.py +1135 -0
  42. pfund_plot-0.0.3/src/pfund_plot/plots/plotly.py +32 -0
  43. pfund_plot-0.0.3/src/pfund_plot/plots/scatter/__init__.py +62 -0
  44. pfund_plot-0.0.3/src/pfund_plot/plots/scatter/bokeh.py +158 -0
  45. pfund_plot-0.0.3/src/pfund_plot/plots/scatter/marker.py +107 -0
  46. pfund_plot-0.0.3/src/pfund_plot/plots/ta.py +6 -0
  47. pfund_plot-0.0.3/src/pfund_plot/renderers/base.py +86 -0
  48. pfund_plot-0.0.3/src/pfund_plot/renderers/browser.py +28 -0
  49. pfund_plot-0.0.3/src/pfund_plot/renderers/desktop.py +109 -0
  50. pfund_plot-0.0.3/src/pfund_plot/renderers/notebook.py +92 -0
  51. pfund_plot-0.0.3/src/pfund_plot/typing.py +29 -0
  52. pfund_plot-0.0.3/src/pfund_plot/utils/__init__.py +176 -0
  53. pfund_plot-0.0.3/src/pfund_plot/utils/bokeh.py +177 -0
  54. pfund_plot-0.0.3/src/pfund_plot/widgets/base.py +76 -0
  55. pfund_plot-0.0.3/src/pfund_plot/widgets/datetime_widget.py +221 -0
  56. pfund_plot-0.0.3/src/pfund_plot/widgets/ticker_widget.py +82 -0
  57. pfund_plot-0.0.1.dev3/LICENSE +0 -201
  58. pfund_plot-0.0.1.dev3/PKG-INFO +0 -101
  59. pfund_plot-0.0.1.dev3/README.md +0 -54
  60. pfund_plot-0.0.1.dev3/pfund_plot/__init__.py +0 -35
  61. pfund_plot-0.0.1.dev3/pfund_plot/cli/__pycache__/__init__.cpython-311.pyc +0 -0
  62. pfund_plot-0.0.1.dev3/pfund_plot/cli/__pycache__/main.cpython-311.pyc +0 -0
  63. pfund_plot-0.0.1.dev3/pfund_plot/cli/commands/__pycache__/config.cpython-311.pyc +0 -0
  64. pfund_plot-0.0.1.dev3/pfund_plot/cli/commands/__pycache__/plot.cpython-311.pyc +0 -0
  65. pfund_plot-0.0.1.dev3/pfund_plot/cli/commands/config.py +0 -81
  66. pfund_plot-0.0.1.dev3/pfund_plot/cli/commands/plot.py +0 -7
  67. pfund_plot-0.0.1.dev3/pfund_plot/cli/main.py +0 -20
  68. pfund_plot-0.0.1.dev3/pfund_plot/composites/composite.py +0 -13
  69. pfund_plot-0.0.1.dev3/pfund_plot/config_handler.py +0 -136
  70. pfund_plot-0.0.1.dev3/pfund_plot/const/__pycache__/paths.cpython-311.pyc +0 -0
  71. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__init__.py +0 -6
  72. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/__init__.cpython-311.pyc +0 -0
  73. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/dashboard_type.cpython-311.pyc +0 -0
  74. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/data_type.cpython-311.pyc +0 -0
  75. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/dataframe_backend.cpython-311.pyc +0 -0
  76. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/display_mode.cpython-311.pyc +0 -0
  77. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/notebook_type.cpython-311.pyc +0 -0
  78. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/plotting_backend.cpython-311.pyc +0 -0
  79. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/dashboard_type.py +0 -8
  80. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/data_type.py +0 -6
  81. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/notebook_type.py +0 -7
  82. pfund_plot-0.0.1.dev3/pfund_plot/const/enums/plotting_backend.py +0 -6
  83. pfund_plot-0.0.1.dev3/pfund_plot/const/paths.py +0 -15
  84. pfund_plot-0.0.1.dev3/pfund_plot/exports/__init__.py +0 -0
  85. pfund_plot-0.0.1.dev3/pfund_plot/layout.py +0 -0
  86. pfund_plot-0.0.1.dev3/pfund_plot/main.py +0 -18
  87. pfund_plot-0.0.1.dev3/pfund_plot/mosaic.py +0 -0
  88. pfund_plot-0.0.1.dev3/pfund_plot/plots/__pycache__/candlestick.cpython-311.pyc +0 -0
  89. pfund_plot-0.0.1.dev3/pfund_plot/plots/__pycache__/dataframe.cpython-311.pyc +0 -0
  90. pfund_plot-0.0.1.dev3/pfund_plot/plots/__pycache__/line.cpython-311.pyc +0 -0
  91. pfund_plot-0.0.1.dev3/pfund_plot/plots/candlestick.py +0 -234
  92. pfund_plot-0.0.1.dev3/pfund_plot/plots/dataframe.py +0 -159
  93. pfund_plot-0.0.1.dev3/pfund_plot/plots/line.py +0 -2
  94. pfund_plot-0.0.1.dev3/pfund_plot/plots/orderbook.py +0 -47
  95. pfund_plot-0.0.1.dev3/pfund_plot/renderer.py +0 -143
  96. pfund_plot-0.0.1.dev3/pfund_plot/templates/__init__.py +0 -2
  97. pfund_plot-0.0.1.dev3/pfund_plot/templates/dashboard.py +0 -13
  98. pfund_plot-0.0.1.dev3/pfund_plot/templates/notebook.py +0 -15
  99. pfund_plot-0.0.1.dev3/pfund_plot/templates/spreadsheet.py +0 -1
  100. pfund_plot-0.0.1.dev3/pfund_plot/templates/template.py +0 -10
  101. pfund_plot-0.0.1.dev3/pfund_plot/types/__pycache__/core.cpython-311.pyc +0 -0
  102. pfund_plot-0.0.1.dev3/pfund_plot/types/__pycache__/literals.cpython-311.pyc +0 -0
  103. pfund_plot-0.0.1.dev3/pfund_plot/types/core.py +0 -11
  104. pfund_plot-0.0.1.dev3/pfund_plot/types/literals.py +0 -6
  105. pfund_plot-0.0.1.dev3/pfund_plot/utils/__pycache__/utils.cpython-311.pyc +0 -0
  106. pfund_plot-0.0.1.dev3/pfund_plot/utils/__pycache__/validate.cpython-311.pyc +0 -0
  107. pfund_plot-0.0.1.dev3/pfund_plot/utils/utils.py +0 -42
  108. pfund_plot-0.0.1.dev3/pfund_plot/utils/validate.py +0 -50
  109. pfund_plot-0.0.1.dev3/pyproject.toml +0 -82
@@ -0,0 +1,146 @@
1
+ Metadata-Version: 2.4
2
+ Name: pfund-plot
3
+ Version: 0.0.3
4
+ Summary: A library for financial data visualization
5
+ Keywords: financial data,plotting,dashboards,charts,data visualization,graphs,plots
6
+ Author: Stephen Yau
7
+ Author-email: Stephen Yau <softwareentrepreneer+pfund-plot@gmail.com>
8
+ License-Expression: Apache-2.0
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Intended Audience :: Financial and Insurance Industry
13
+ Classifier: Intended Audience :: Information Technology
14
+ Classifier: Topic :: Office/Business :: Financial :: Investment
15
+ Classifier: Topic :: Scientific/Engineering :: Visualization
16
+ Classifier: Topic :: Software Development :: Libraries
17
+ Classifier: Typing :: Typed
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Requires-Dist: pfeed>=0.0.15
22
+ Requires-Dist: panel>=1.9.3
23
+ Requires-Dist: hvplot>=0.12.2
24
+ Requires-Dist: dayplot>=0.5.1
25
+ Requires-Dist: anywidget>=0.11.0 ; sys_platform != 'emscripten'
26
+ Requires-Dist: ipywidgets-bokeh>=1.7.0 ; sys_platform != 'emscripten'
27
+ Requires-Dist: pywebview>=6.2.1 ; sys_platform != 'emscripten'
28
+ Requires-Dist: datashader>=0.19.1 ; sys_platform != 'emscripten'
29
+ Requires-Dist: altair>=6.1.0 ; extra == 'altair'
30
+ Requires-Dist: vegafusion>=2.0.3 ; extra == 'altair'
31
+ Requires-Dist: vl-convert-python>=1.9.0.post1 ; extra == 'altair'
32
+ Requires-Dist: jupyter-bokeh>=4.0.5 ; extra == 'jupyter'
33
+ Requires-Dist: notebook>=7.5.7 ; extra == 'jupyter'
34
+ Requires-Dist: papermill>=2.7.0 ; extra == 'jupyter'
35
+ Requires-Dist: voila>=0.5.12 ; extra == 'jupyter'
36
+ Requires-Dist: marimo[recommended,lsp]>=0.23.9 ; extra == 'marimo'
37
+ Requires-Dist: matplotlib>=3.10.9 ; extra == 'matplotlib'
38
+ Requires-Dist: plotly>=6.8.0 ; extra == 'plotly'
39
+ Requires-Python: >=3.11
40
+ Project-URL: homepage, https://pfund-plot.pfund.ai
41
+ Project-URL: repository, https://github.com/PFund-Software-Ltd/pfund-plot
42
+ Project-URL: documentation, https://pfund-plot.pfund.ai/doc
43
+ Provides-Extra: altair
44
+ Provides-Extra: jupyter
45
+ Provides-Extra: marimo
46
+ Provides-Extra: matplotlib
47
+ Provides-Extra: plotly
48
+ Description-Content-Type: text/markdown
49
+
50
+ # `pfund-plot`: Financial Charts in One Line of Code
51
+
52
+ [![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?logo=discord&logoColor=white)](https://discord.gg/vqpS94tpdp)
53
+ [![X](https://img.shields.io/twitter/follow/pfund_ai?style=social)](https://x.com/pfund_ai)
54
+ [![Downloads](https://static.pepy.tech/badge/pfund-plot/month)](https://pepy.tech/project/pfund-plot)
55
+ [![PyPI](https://img.shields.io/pypi/v/pfund-plot.svg?cacheSeconds=300)](https://pypi.org/project/pfund-plot)
56
+ ![PyPI - Support Python Versions](https://img.shields.io/pypi/pyversions/pfund-plot?cacheSeconds=300)
57
+ [![afterpython](https://afterpython.org/shield.svg)](https://afterpython.org)
58
+ [![Discussions](https://img.shields.io/badge/Discussions-Let's%20Chat-green)](https://github.com/PFund-Software-Ltd/pfund-plot/discussions)
59
+ [![Jupyter Notebook](https://img.shields.io/badge/jupyter-notebook-orange?logo=jupyter)](https://jupyter.org)
60
+ [![Marimo](https://marimo.io/shield.svg)](https://marimo.io)
61
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/PFund-Software-Ltd/pfund-plot)
62
+ [![View Code Wiki](https://assets.codewiki.google/readme-badge/static.svg)](https://codewiki.google/github.com/pfund-software-ltd/pfund-plot?utm_source=badge&utm_medium=github&utm_campaign=github.com/pfund-software-ltd/pfund-plot)
63
+ <!-- ![PyPI downloads](https://img.shields.io/pypi/dm/pfund-plot?label=downloads&cacheSeconds=86400) -->
64
+ <!-- ![GitHub stars](https://img.shields.io/github/stars/PFund-Software-Ltd/pfund-plot?style=social) -->
65
+
66
+
67
+ ## TL;DR: pfund-plot handles the plotting libraries, so traders just get charts that work
68
+
69
+ ## Problem
70
+ Traders often need to quickly visualize their data without investing time in learning new tools.
71
+ For example, plotting a candlestick should be as simple as writing a single line of code.
72
+
73
+ ## Solution
74
+ We created a high-level financial visualization layer that combines the best features from existing plotting libraries into an easy-to-use interface.
75
+
76
+ ---
77
+ <img src="afterpython/static/candlestick.gif" alt="pfund-plot candlestick streaming example" width="450">
78
+
79
+ ---
80
+
81
+ `pfund-plot` is a financial visualization layer on top of existing plotting libraries, giving traders a simple, domain-specific interface for plotting and streaming market data.
82
+
83
+ ## Core Features
84
+ - [x] Multi-Display Mode: support displaying plots in a *Jupyter notebook*, *Marimo notebook*, *browser* and *desktop window*
85
+ - [x] Intuitive & Chainable API: `plt.ohlc(df).style(...).control(...).mode(...).show()`
86
+ - [x] Streaming Plots: support streaming data in real-time
87
+ - [x] DataFrame Agnostic: support pandas, polars, and dask
88
+ - [x] Financial Plots: plot financial data by just one function call
89
+ - [x] Combine multiple plots into a dashboard quickly for visualization
90
+
91
+
92
+ ## Installation
93
+ ```bash
94
+ pip install pfund-plot
95
+ ```
96
+
97
+ ## Quickstart
98
+ ### 1. Plotting in a Jupyter or Marimo Notebook
99
+ > To use data sources other than Bybit, please go to [pfeed](https://github.com/PFund-Software-Ltd/pfeed) and install the corresponding extras. For example: `pip install "pfeed[data_source1, data_source2]"`
100
+ ```python
101
+ import pfeed as pe
102
+ import pfund_plot as plt
103
+
104
+ feed = pe.Bybit().market_feed
105
+ result = feed.download(product='BTC_USDT_PERP', resolution='1h', rollback_period='1d')
106
+ df = result.data.collect()
107
+
108
+ # Notebook mode:
109
+ plt.ohlc(df)
110
+ ```
111
+
112
+ ### 2. Plotting in a Python Script
113
+ ```python
114
+ # Browser mode:
115
+ plt.ohlc(df).mode('browser').show()
116
+
117
+ # Desktop mode:
118
+ if __name__ == "__main__": # Required because desktop mode uses multiprocessing.
119
+ plt.ohlc(df).mode('desktop').show()
120
+ ```
121
+
122
+ ### 3. Streaming a Plot
123
+ ```python
124
+ # Streaming requires pipeline_mode=True.
125
+ feed = pe.Bybit(pipeline_mode=True).market_feed
126
+ feed.stream(product='BTC_USDT_PERP', resolution='1s')
127
+
128
+ # In a Python script:
129
+ plt.ohlc(feed).control(update_interval=1000).mode('browser') # or mode('desktop') under if __name__ == "__main__"
130
+
131
+ # In a notebook environment (not recommended to start streaming in a notebook unless you know what you're doing):
132
+ # await plt.ohlc(feed).control(update_interval=1000).show_async()
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Tapping into the JavaScript World
138
+ Python developers sometimes envy the JavaScript visualization ecosystem for its rich set of interactive charts and dashboards. With `pfund-plot`, they can still enjoy the benefits of the JavaScript world while keeping the same Python-first API. For example:
139
+ ```python
140
+ plt.ohlc(df).backend('svelte')
141
+ ```
142
+ This renders the following chart using TradingView's [Lightweight Charts](https://github.com/tradingview/lightweight-charts):
143
+
144
+ <img src="afterpython/static/tradingview.png" alt="pfund-plot TradingView Lightweight Charts example" width="450">
145
+
146
+ > This is meant as a showcase rather than a core direction: `pfund-plot` remains Python-first, and JavaScript-backed charts are supported where they fit naturally. If you want to bring more useful JavaScript visualizations into `pfund-plot`, contributions are welcome.
@@ -0,0 +1,97 @@
1
+ # `pfund-plot`: Financial Charts in One Line of Code
2
+
3
+ [![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?logo=discord&logoColor=white)](https://discord.gg/vqpS94tpdp)
4
+ [![X](https://img.shields.io/twitter/follow/pfund_ai?style=social)](https://x.com/pfund_ai)
5
+ [![Downloads](https://static.pepy.tech/badge/pfund-plot/month)](https://pepy.tech/project/pfund-plot)
6
+ [![PyPI](https://img.shields.io/pypi/v/pfund-plot.svg?cacheSeconds=300)](https://pypi.org/project/pfund-plot)
7
+ ![PyPI - Support Python Versions](https://img.shields.io/pypi/pyversions/pfund-plot?cacheSeconds=300)
8
+ [![afterpython](https://afterpython.org/shield.svg)](https://afterpython.org)
9
+ [![Discussions](https://img.shields.io/badge/Discussions-Let's%20Chat-green)](https://github.com/PFund-Software-Ltd/pfund-plot/discussions)
10
+ [![Jupyter Notebook](https://img.shields.io/badge/jupyter-notebook-orange?logo=jupyter)](https://jupyter.org)
11
+ [![Marimo](https://marimo.io/shield.svg)](https://marimo.io)
12
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/PFund-Software-Ltd/pfund-plot)
13
+ [![View Code Wiki](https://assets.codewiki.google/readme-badge/static.svg)](https://codewiki.google/github.com/pfund-software-ltd/pfund-plot?utm_source=badge&utm_medium=github&utm_campaign=github.com/pfund-software-ltd/pfund-plot)
14
+ <!-- ![PyPI downloads](https://img.shields.io/pypi/dm/pfund-plot?label=downloads&cacheSeconds=86400) -->
15
+ <!-- ![GitHub stars](https://img.shields.io/github/stars/PFund-Software-Ltd/pfund-plot?style=social) -->
16
+
17
+
18
+ ## TL;DR: pfund-plot handles the plotting libraries, so traders just get charts that work
19
+
20
+ ## Problem
21
+ Traders often need to quickly visualize their data without investing time in learning new tools.
22
+ For example, plotting a candlestick should be as simple as writing a single line of code.
23
+
24
+ ## Solution
25
+ We created a high-level financial visualization layer that combines the best features from existing plotting libraries into an easy-to-use interface.
26
+
27
+ ---
28
+ <img src="afterpython/static/candlestick.gif" alt="pfund-plot candlestick streaming example" width="450">
29
+
30
+ ---
31
+
32
+ `pfund-plot` is a financial visualization layer on top of existing plotting libraries, giving traders a simple, domain-specific interface for plotting and streaming market data.
33
+
34
+ ## Core Features
35
+ - [x] Multi-Display Mode: support displaying plots in a *Jupyter notebook*, *Marimo notebook*, *browser* and *desktop window*
36
+ - [x] Intuitive & Chainable API: `plt.ohlc(df).style(...).control(...).mode(...).show()`
37
+ - [x] Streaming Plots: support streaming data in real-time
38
+ - [x] DataFrame Agnostic: support pandas, polars, and dask
39
+ - [x] Financial Plots: plot financial data by just one function call
40
+ - [x] Combine multiple plots into a dashboard quickly for visualization
41
+
42
+
43
+ ## Installation
44
+ ```bash
45
+ pip install pfund-plot
46
+ ```
47
+
48
+ ## Quickstart
49
+ ### 1. Plotting in a Jupyter or Marimo Notebook
50
+ > To use data sources other than Bybit, please go to [pfeed](https://github.com/PFund-Software-Ltd/pfeed) and install the corresponding extras. For example: `pip install "pfeed[data_source1, data_source2]"`
51
+ ```python
52
+ import pfeed as pe
53
+ import pfund_plot as plt
54
+
55
+ feed = pe.Bybit().market_feed
56
+ result = feed.download(product='BTC_USDT_PERP', resolution='1h', rollback_period='1d')
57
+ df = result.data.collect()
58
+
59
+ # Notebook mode:
60
+ plt.ohlc(df)
61
+ ```
62
+
63
+ ### 2. Plotting in a Python Script
64
+ ```python
65
+ # Browser mode:
66
+ plt.ohlc(df).mode('browser').show()
67
+
68
+ # Desktop mode:
69
+ if __name__ == "__main__": # Required because desktop mode uses multiprocessing.
70
+ plt.ohlc(df).mode('desktop').show()
71
+ ```
72
+
73
+ ### 3. Streaming a Plot
74
+ ```python
75
+ # Streaming requires pipeline_mode=True.
76
+ feed = pe.Bybit(pipeline_mode=True).market_feed
77
+ feed.stream(product='BTC_USDT_PERP', resolution='1s')
78
+
79
+ # In a Python script:
80
+ plt.ohlc(feed).control(update_interval=1000).mode('browser') # or mode('desktop') under if __name__ == "__main__"
81
+
82
+ # In a notebook environment (not recommended to start streaming in a notebook unless you know what you're doing):
83
+ # await plt.ohlc(feed).control(update_interval=1000).show_async()
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Tapping into the JavaScript World
89
+ Python developers sometimes envy the JavaScript visualization ecosystem for its rich set of interactive charts and dashboards. With `pfund-plot`, they can still enjoy the benefits of the JavaScript world while keeping the same Python-first API. For example:
90
+ ```python
91
+ plt.ohlc(df).backend('svelte')
92
+ ```
93
+ This renders the following chart using TradingView's [Lightweight Charts](https://github.com/tradingview/lightweight-charts):
94
+
95
+ <img src="afterpython/static/tradingview.png" alt="pfund-plot TradingView Lightweight Charts example" width="450">
96
+
97
+ > This is meant as a showcase rather than a core direction: `pfund-plot` remains Python-first, and JavaScript-backed charts are supported where they fit naturally. If you want to bring more useful JavaScript visualizations into `pfund-plot`, contributions are welcome.
@@ -0,0 +1,85 @@
1
+ [project]
2
+ name = "pfund-plot"
3
+ version = "0.0.3"
4
+ description = "A library for financial data visualization"
5
+ license = "Apache-2.0"
6
+ authors = [
7
+ {name = "Stephen Yau", email = "softwareentrepreneer+pfund-plot@gmail.com"}
8
+ ]
9
+ readme = "README.md"
10
+ keywords = ["financial data", "plotting", "dashboards", "charts", "data visualization", "graphs", "plots"]
11
+ classifiers = [
12
+ "Operating System :: OS Independent",
13
+ "Intended Audience :: Developers",
14
+ "Intended Audience :: Science/Research",
15
+ "Intended Audience :: Financial and Insurance Industry",
16
+ "Intended Audience :: Information Technology",
17
+ "Topic :: Office/Business :: Financial :: Investment",
18
+ "Topic :: Scientific/Engineering :: Visualization",
19
+ "Topic :: Software Development :: Libraries",
20
+ "Typing :: Typed",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ ]
25
+ requires-python = ">=3.11"
26
+ dependencies = [
27
+ "pfeed>=0.0.15",
28
+ "panel>=1.9.3",
29
+ "hvplot>=0.12.2",
30
+ "dayplot>=0.5.1",
31
+ "anywidget>=0.11.0 ; sys_platform != 'emscripten'",
32
+ "ipywidgets-bokeh>=1.7.0 ; sys_platform != 'emscripten'",
33
+ "pywebview>=6.2.1 ; sys_platform != 'emscripten'",
34
+ "datashader>=0.19.1 ; sys_platform != 'emscripten'",
35
+ ]
36
+
37
+ [project.optional-dependencies]
38
+ marimo = ["marimo[recommended,lsp]>=0.23.9"]
39
+ jupyter = [
40
+ "jupyter-bokeh>=4.0.5",
41
+ "notebook>=7.5.7",
42
+ "papermill>=2.7.0",
43
+ "voila>=0.5.12",
44
+ ]
45
+ matplotlib = ["matplotlib>=3.10.9"]
46
+ plotly = ["plotly>=6.8.0"]
47
+ altair = [
48
+ "altair>=6.1.0",
49
+ "vegafusion>=2.0.3",
50
+ "vl-convert-python>=1.9.0.post1",
51
+ ]
52
+
53
+ [project.scripts]
54
+ plt = "pfund_plot.__main__:run_cli"
55
+
56
+ [project.entry-points."pfund_shell.commands"]
57
+ plt = "pfund_plot.cli:pfund_plot_group"
58
+
59
+ [project.urls]
60
+ homepage = "https://pfund-plot.pfund.ai"
61
+ repository = "https://github.com/PFund-Software-Ltd/pfund-plot"
62
+ documentation = "https://pfund-plot.pfund.ai/doc"
63
+
64
+ [build-system]
65
+ requires = ["uv_build>=0.11.19,<0.12.0"]
66
+ build-backend = "uv_build"
67
+
68
+ [tool.pyright]
69
+ # typeCheckingMode = "basic"
70
+ reportAny = false
71
+ reportExplicitAny = false
72
+ reportUnnecessaryIsInstance = false
73
+ reportIncompatibleVariableOverride = false
74
+ reportIncompatibleMethodOverride = false
75
+ reportRedeclaration = false
76
+ reportUnreachable = false
77
+ reportImportCycles = false
78
+ reportPrivateUsage = false
79
+ reportMissingTypeStubs = false
80
+ reportUnannotatedClassAttribute = false
81
+ reportImplicitOverride = false
82
+
83
+ [tool.uv.build-backend]
84
+ module-name = "pfund_plot"
85
+ module-root = "src"
@@ -0,0 +1,178 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ if TYPE_CHECKING:
6
+ from pfund_plot.plots.altair import (
7
+ Altair as altair,
8
+ )
9
+ from pfund_plot.plots.altair import (
10
+ Altair as vega,
11
+ )
12
+ from pfund_plot.plots.area import (
13
+ Area as area,
14
+ )
15
+ from pfund_plot.plots.bar import (
16
+ Bar as bar,
17
+ )
18
+ from pfund_plot.plots.bokeh import (
19
+ Bokeh as bokeh,
20
+ )
21
+ from pfund_plot.plots.candlestick import (
22
+ Candlestick as candlestick,
23
+ )
24
+ from pfund_plot.plots.candlestick import (
25
+ Candlestick as kline,
26
+ )
27
+ from pfund_plot.plots.candlestick import (
28
+ Candlestick as ohlc,
29
+ )
30
+ from pfund_plot.plots.holoviews import (
31
+ Holoviews as holoviews,
32
+ )
33
+ from pfund_plot.plots.holoviews import (
34
+ Holoviews as hv,
35
+ )
36
+ from pfund_plot.plots.label import (
37
+ Label as label,
38
+ )
39
+ from pfund_plot.plots.layout import (
40
+ Layout as layout,
41
+ )
42
+ from pfund_plot.plots.layout.tabs import (
43
+ Tabs as tabs,
44
+ )
45
+ from pfund_plot.plots.line import (
46
+ Line as line,
47
+ )
48
+ from pfund_plot.plots.matplotlib import (
49
+ Matplotlib as matplotlib,
50
+ )
51
+ from pfund_plot.plots.matplotlib import (
52
+ Matplotlib as mpl,
53
+ )
54
+ from pfund_plot.plots.plotly import (
55
+ Plotly as plotly,
56
+ )
57
+ from pfund_plot.plots.scatter import (
58
+ Scatter as scatter,
59
+ )
60
+ from pfund_plot.plots.scatter.marker import (
61
+ Marker as marker,
62
+ )
63
+
64
+ # NOTE: data update in anywidget (backend=svelte) may have issues (especially in marimo) after loading panel extensions
65
+ # if anywidget+svelte backend is not working, try to comment this out
66
+ #
67
+ # plotly/vega resolve to panel.models.* (bundled with Panel) — they don't import the
68
+ # plotly/altair libs, so they're safe even when those optional extras aren't installed.
69
+ # "ipywidgets" pulls in panel.io.ipywidget -> ipywidgets_bokeh, which is absent in WASM
70
+ # (and where the anywidget/svelte backend isn't available anyway), so guard only that one.
71
+ import importlib.util
72
+
73
+ import panel as pn
74
+
75
+ from pfund_plot.config import configure, get_config
76
+
77
+ _panel_extensions = ["plotly", "vega"]
78
+ if importlib.util.find_spec("ipywidgets_bokeh") is not None:
79
+ _panel_extensions.append("ipywidgets")
80
+ pn.extension(*_panel_extensions)
81
+ # NOTE: this MUST be True, otherwise, some widgets won't work properly, e.g. candlestick widgets, slider and input will both trigger each other due to panel's async update, which leads to infinite loop.
82
+ pn.config.throttled = (
83
+ True # If panel sliders and inputs should be throttled until release of mouse.
84
+ )
85
+
86
+
87
+ def __getattr__(name: str):
88
+ if name == "__version__":
89
+ from importlib.metadata import version
90
+
91
+ return version("pfund_plot")
92
+ elif name == "plotly":
93
+ from pfund_plot.plots.plotly import Plotly
94
+
95
+ return Plotly
96
+ elif name in ("candlestick", "ohlc", "kline"):
97
+ from pfund_plot.plots.candlestick import Candlestick
98
+
99
+ return Candlestick
100
+ elif name == "line":
101
+ from pfund_plot.plots.line import Line
102
+
103
+ return Line
104
+ elif name == "area":
105
+ from pfund_plot.plots.area import Area
106
+
107
+ return Area
108
+ elif name == "layout":
109
+ from pfund_plot.plots.layout import Layout
110
+
111
+ return Layout
112
+ elif name == "tabs":
113
+ from pfund_plot.plots.layout.tabs import Tabs
114
+
115
+ return Tabs
116
+ elif name == "scatter":
117
+ from pfund_plot.plots.scatter import Scatter
118
+
119
+ return Scatter
120
+ elif name == "marker":
121
+ from pfund_plot.plots.scatter.marker import Marker
122
+
123
+ return Marker
124
+ elif name == "label":
125
+ from pfund_plot.plots.label import Label
126
+
127
+ return Label
128
+ elif name == "bar":
129
+ from pfund_plot.plots.bar import Bar
130
+
131
+ return Bar
132
+ elif name in ("altair", "vega"):
133
+ from pfund_plot.plots.altair import Altair
134
+
135
+ return Altair
136
+ elif name in ("matplotlib", "mpl"):
137
+ from pfund_plot.plots.matplotlib import Matplotlib
138
+
139
+ return Matplotlib
140
+ elif name == "bokeh":
141
+ from pfund_plot.plots.bokeh import Bokeh
142
+
143
+ return Bokeh
144
+ elif name in ("holoviews", "hv"):
145
+ from pfund_plot.plots.holoviews import Holoviews
146
+
147
+ return Holoviews
148
+ else:
149
+ raise AttributeError(f"'{__name__}' has no attribute '{name}'")
150
+
151
+
152
+ __all__ = (
153
+ "altair",
154
+ "area",
155
+ "bar",
156
+ "bokeh",
157
+ "candlestick",
158
+ "configure",
159
+ "get_config",
160
+ "holoviews",
161
+ "hv",
162
+ "kline",
163
+ "label",
164
+ "layout",
165
+ "line",
166
+ "marker",
167
+ "matplotlib",
168
+ "mpl",
169
+ "ohlc",
170
+ "plotly",
171
+ "scatter",
172
+ "tabs",
173
+ "vega",
174
+ )
175
+
176
+
177
+ def __dir__():
178
+ return sorted(__all__)
@@ -0,0 +1,9 @@
1
+ def run_cli() -> None:
2
+ """Application Entrypoint."""
3
+ from pfund_plot.cli import pfund_plot_group
4
+
5
+ pfund_plot_group(obj={})
6
+
7
+
8
+ if __name__ == "__main__":
9
+ run_cli()
@@ -1,4 +1,3 @@
1
1
  from pfund_plot.cli.main import pfund_plot_group
2
2
 
3
-
4
- __all__ = ["pfund_plot_group"]
3
+ __all__ = ["pfund_plot_group"]
@@ -0,0 +1,15 @@
1
+ import subprocess
2
+ import sys
3
+ from pathlib import Path
4
+
5
+ import click
6
+
7
+ GALLERY_DIR = Path(__file__).parent
8
+
9
+
10
+ @click.command(hidden=True)
11
+ def gallery():
12
+ """Open the gallery to visually verify all supported plots."""
13
+ script = GALLERY_DIR / "gallery_marimo.py"
14
+ result = subprocess.run(["marimo", "edit", str(script)], check=False)
15
+ sys.exit(result.returncode)