df and sr accessor enhancements

This commit is contained in:
David Brazda
2024-10-04 11:54:24 +02:00
parent 7986aa9195
commit c4356bef3a
10 changed files with 195 additions and 20 deletions

View File

@ -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.
<img width="1005" alt="image" src="https://github.com/drew2323/lightweight-charts-python/assets/28433232/856c32aa-e0ff-4de0-b4a2-befc34adb571">
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()
```
![alt text](image-2.png)
```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
```
![alt text](image-1.png)
```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.)
```
![alt text](image-3.png)
```python
ohlcv_df.lw.plot(left=[(angle_series, "angle_momentum")]) #Another line is displayed on top of OHLCV on left scale
```
![alt text](image-4.png)
```python
ohlcv_complex_df.lw.plot() #df containing ohlcv and other columns
```
![alt text](image-5.png)
```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
<div align="center">
# lightweight-charts-python
# lightweight-charts-python - forked from
[![PyPi Release](https://img.shields.io/pypi/v/lightweight-charts?color=32a852&label=PyPi)](https://pypi.org/project/lightweight-charts/)
[![Made with Python](https://img.shields.io/badge/Python-3.8+-c7a002?logo=python&logoColor=white)](https://python.org "Go to Python homepage")

BIN
image-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
image-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
image-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
image-4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
image-5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -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
from .helpers import chart, Panel, PlotSRAccessor, PlotDFAccessor

View File

@ -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

View File

@ -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=[