diff --git a/README.md b/README.md
index ed2e3af..6c5d752 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,49 @@
Fork of the original [lightweight-charts](louisnw01/lightweight-charts-python) with enhancements and supporting vectorbtpro workflow
-* legends cookie matching line colors
-* automatic colors picks if not provided
-* support for left and mid price scales
+* legend color matching each line color
+* automatic color assignment if not provided
+* support for multiple scales (right, left, middle1, middle2, histogram)
* accepts df,pd.series or vectorbtpro indicator object (including unpacking multi outputs)
* new markers_set method allowing to set pd.series or dataframe as markers input
-* supports simple df/sr accessors `close.lw.plot()` for quick visualization of single panel chart
-* supports `ch = chart([pane1, pane2], sync=True, title="Title", size="m")` to quickly display chart with N panes (`Panels`). Also supports syncing the Panels `sync=True` or using xloc.
+* for quick display supports simple df/sr accessors `close.lw.plot()` for quick visualization of single panel chart
+* df accessor unpacks dataframe columns and display them accordingly (ohlcv as ohlcv, vwap on the right, rsi on the left scale etc.)
+* multipanes support `ch = chart([pane1, pane2], sync=True, title="Title", size="m")` to quickly display chart with N panes (`Panels`). Also supports syncing the Panels `sync=True` or using xloc.
-It should be installed directly from this repository.
+## Instalation
+Directly from the repository
+
+```pip install git+https://github.com/drew2323/lightweight-charts-python.git```
## Examples
```python
-from lightweight_charts import chart, Panel
+from lightweight_charts import chart, Panel, PlotSRAccessor, PlotDFAccessor
#one liner, displays close series as line on single Panel
-close.lw.plot()
-
+close_sr.lw.plot()
+```
+
+```python
+close_sr.lw.plot(size="m") #on medium panesize
+close_se.lw.plot(histogram=(trade_series, "trades")) #number of trades as histogram is displayed on top of that
+```
+
+```python
+#one liner to display OHLCV
+ohlcv_df.lw.plot() #if dataframe contains other columns they are displayed too - based on standard settings (rsi-on the left, vwap - right etc.)
+```
+
+```python
+ohlcv_df.lw.plot(left=[(angle_series, "angle_momentum")]) #Another line is displayed on top of OHLCV on left scale
+```
+
+```python
+ohlcv_complex_df.lw.plot() #df containing ohlcv and other columns
+```
+
+```python
#quick few liner, displays close series with label "close" on right pricescale and rsi on left price scale, all on single Panel
pane1 = Panel(
right=[(close, "close")],
@@ -53,7 +77,7 @@ pane2 = Panel(
)
#display both Panels, sync them and pick size, use xloc
-ch = chart([pane1, pane2], sync=True, title="Title", size="l", xloc=slice("1-1-2024","1-2-2024")
+ch = chart([pane1, pane2], sync=True, title="Title", size="l", xloc=slice("1-1-2024","1-2-2024"))
```
@@ -88,7 +112,7 @@ ch = chart([pane1], title="Chart with EntryShort/ExitShort (yellow) and EntryLon
-# lightweight-charts-python
+# lightweight-charts-python - forked from
[](https://pypi.org/project/lightweight-charts/)
[](https://python.org "Go to Python homepage")
diff --git a/image-1.png b/image-1.png
new file mode 100644
index 0000000..13a3346
Binary files /dev/null and b/image-1.png differ
diff --git a/image-2.png b/image-2.png
new file mode 100644
index 0000000..4b77e2c
Binary files /dev/null and b/image-2.png differ
diff --git a/image-3.png b/image-3.png
new file mode 100644
index 0000000..0a6c246
Binary files /dev/null and b/image-3.png differ
diff --git a/image-4.png b/image-4.png
new file mode 100644
index 0000000..83e8625
Binary files /dev/null and b/image-4.png differ
diff --git a/image-5.png b/image-5.png
new file mode 100644
index 0000000..1ad3fc2
Binary files /dev/null and b/image-5.png differ
diff --git a/image.png b/image.png
new file mode 100644
index 0000000..13a3346
Binary files /dev/null and b/image.png differ
diff --git a/lightweight_charts/__init__.py b/lightweight_charts/__init__.py
index 156b719..69c97ec 100644
--- a/lightweight_charts/__init__.py
+++ b/lightweight_charts/__init__.py
@@ -2,4 +2,4 @@ from .abstract import AbstractChart, Window
from .chart import Chart
from .widgets import JupyterChart
from .polygon import PolygonChart
-from .helpers import chart, Panel, PlotAccessor
\ No newline at end of file
+from .helpers import chart, Panel, PlotSRAccessor, PlotDFAccessor
\ No newline at end of file
diff --git a/lightweight_charts/helpers.py b/lightweight_charts/helpers.py
index 1fbca38..1ad22da 100644
--- a/lightweight_charts/helpers.py
+++ b/lightweight_charts/helpers.py
@@ -4,15 +4,54 @@ from .util import (
)
import pandas as pd
+def append_or_extend(target_list, value):
+ if isinstance(value, list):
+ target_list.extend(value) # Extend if it's a list
+ else:
+ target_list.append(value) # Append if it's a single value
+
+def extend_kwargs(ohlcv, right, left, middle1, middle2, histogram, kwargs):
+ """
+ Mutate lists based on kwargs for accessor.
+ Used when user added additional series to kwargs when using accessor.
+ """
+ if 'ohlcv' in kwargs:
+ ohlcv = kwargs['ohlcv'] #ohlcv is only a tuple
+ if 'left' in kwargs:
+ append_or_extend(left, kwargs['left'])
+ if 'right' in kwargs:
+ append_or_extend(right, kwargs['right'])
+ if 'histogram' in kwargs:
+ append_or_extend(histogram, kwargs['histogram'])
+ if 'middle1' in kwargs:
+ append_or_extend(middle1, kwargs['middle1'])
+ if 'middle2' in kwargs:
+ append_or_extend(middle1, kwargs['middle2'])
+
+ return ohlcv #as tuple is immutable
+
# Register the custom accessor
@pd.api.extensions.register_series_accessor("lw")
-class PlotAccessor:
+class PlotSRAccessor:
"""
- Custom plot accessor for pandas series.
+ Custom plot accessor for pandas series. Quickly displays series values as line on the single pane.
+
+ Also additional priceseries can be added on top of them. They can be added
+ for each scale in the correct format - either as tuple(OHLCV) or as list of tuple (others)
+
+ # input parameter / expected format:
+ # ohlcv=(), #(series, entries, exits, other_markers)
+ # histogram=[], # [(series, name, "rgba(53, 94, 59, 0.6)", opacity)]
+ # right=[],
+ # left=[], #[(series, name, entries, exits, other_markers)]
+ # middle1=[],
+ # middle2=[],
+
Usage: s
- series.lw.plot()
- series.lw.plot(size="m")
+ series.lw.plot() #plot series as line
+ series.lw.plot(size="m") #on medium panesize
+ series.lw.plot(histogram=(trade_series, "trades")) #plot histogram with trades on top of that
"""
def __init__(self, pandas_obj):
self._obj = pandas_obj
@@ -20,11 +59,123 @@ class PlotAccessor:
def plot(self, **kwargs):
if "size" not in kwargs:
kwargs["size"] = "xs"
+
+ ohlcv = ()
+ right = []
+ left = []
+ middle1 = []
+ middle2 = []
+ histogram = []
+
+ #if there are additional series in kwargs add them too
+ #ohlcv is returned as it is tuple thus immutable
+ ohlcv = extend_kwargs(ohlcv, right, left, middle1, middle2, histogram, kwargs)
+
+ right.append((self._obj,"line"))
+
pane1 = Panel(
- right=[(self._obj, "line")],
- )
+ ohlcv=ohlcv,
+ histogram=histogram,
+ right=right,
+ left=left,
+ middle1=middle1,
+ middle2=middle2
+ )
+
ch = chart([pane1], **kwargs)
+@pd.api.extensions.register_dataframe_accessor("lw")
+class PlotDFAccessor:
+ """
+ Custom plot accessor for dataframe. Quickly displays all columns on the single pane.
+
+ Series type is automatically extracted for each column based on following setting:
+ scale / columns
+ ohlcv = ['close', 'volume', 'open', 'high', 'low']
+ right = ['vwap']
+ left = ['rsi']
+ middle1 = []
+ middle2 = []
+ histogram = ['buyvolume', 'sellvolume', 'trades']
+
+ Also additional priceseries can be added on top of them as parameters. They can be added
+ for each scale in the correct format - either as tuple(OHLCV) or as list of tuple (others)
+
+ # input parameter / expected format:
+ # ohlcv=(), #(series, entries, exits, other_markers)
+ # histogram=[], # [(series, name, "rgba(53, 94, 59, 0.6)", opacity)]
+ # right=[],
+ # left=[], #[(series, name, entries, exits, other_markers)]
+ # middle1=[],
+ # middle2=[],
+
+
+ Usage:
+ ohlcv_df.lw.plot()
+ ohlcv_df.lw.plot(size="m")
+ ohlcv_df.lw.plot(right=(rsi_series, "rsi"))
+ ohlcv_df.lw.plot(right=[(rsi_series, "rsi"), (angle_series, "angle")])
+ basic_data.data[SYMBOL].lw.plot(histogram=(basic_data.data[SYMBOL].close, "close"), size="m")
+ """
+ def __init__(self, pandas_obj):
+ self._obj = pandas_obj
+
+ def plot(self, **kwargs):
+ if "size" not in kwargs:
+ kwargs["size"] = "xs"
+
+ #default settings for each pricescale
+ ohlcv_cols = ['close', 'volume', 'open', 'high', 'low']
+ right_cols = ['vwap']
+ left_cols = ['rsi']
+ middle1_cols = []
+ middle2_cols = []
+ histogram_cols = ['buyvolume', 'sellvolume', 'trades']
+
+ ohlcv = ()
+ right = []
+ left = []
+ middle1 = []
+ middle2 = []
+ histogram = []
+
+ for col in self._obj.columns:
+ if col in right_cols:
+ right.append((self._obj[col],col,))
+ if col in histogram_cols:
+ histogram.append((self._obj[col],col,))
+ if col in left_cols:
+ left.append((self._obj[col],col,))
+ if col in middle1_cols:
+ middle1_cols.append((self._obj[col],col,))
+ if col in middle2_cols:
+ middle2_cols.append((self._obj[col],col,))
+
+ ohlcv = (self._obj[ohlcv_cols],)
+
+ #if there are additional series in kwargs add them too
+ ohlcv = extend_kwargs(ohlcv, right, left, middle1, middle2, histogram, kwargs)
+
+ pane1 = Panel(
+ ohlcv=ohlcv,
+ histogram=histogram,
+ right=right,
+ left=left,
+ middle1=middle1,
+ middle2=middle2
+ )
+
+ ch = chart([pane1], **kwargs)
+
+ # pane1 = Panel(
+ # ohlcv=(), #(series, entries, exits, other_markers)
+ # histogram=[], # [(series, name, "rgba(53, 94, 59, 0.6)", opacity)]
+ # right=[],
+ # left=[], #[(series, name, entries, exits, other_markers)]
+ # middle1=[],
+ # middle2=[],
+ # )
+
class Panel:
"""
A class to represent a panel in a chart.
@@ -118,7 +269,7 @@ class Panel:
self.precision = precision
-def chart(panes: list[Panel], sync=False, title='', size="m", xloc=None, session: str="9:30:00, 09:30:05", precision=None):
+def chart(panes: list[Panel], sync=False, title='', size="m", xloc=None, session: str="9:30:00, 09:30:05", precision=None, **kwargs):
"""
Function to fast render a chart with multiple panes. This function manipulates graphical
output or interfaces with an external framework to display charts with synchronized
diff --git a/setup.py b/setup.py
index 09be3b8..e3244c0 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@ with open('README.md', 'r', encoding='utf-8') as f:
setup(
name='lightweight_charts',
- version='2.1.7',
+ version='2.2.0',
packages=find_packages(),
python_requires='>=3.8',
install_requires=[