plotly-extend-wrapper 1.2.0__tar.gz → 1.4.0__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.
- {plotly_extend_wrapper-1.2.0 → plotly_extend_wrapper-1.4.0}/PKG-INFO +30 -19
- {plotly_extend_wrapper-1.2.0 → plotly_extend_wrapper-1.4.0}/README.md +20 -12
- {plotly_extend_wrapper-1.2.0 → plotly_extend_wrapper-1.4.0}/plotly_extend_wrapper/__init__.py +1 -1
- plotly_extend_wrapper-1.4.0/plotly_extend_wrapper/common.py +22 -0
- {plotly_extend_wrapper-1.2.0 → plotly_extend_wrapper-1.4.0}/plotly_extend_wrapper/wrapper.py +94 -13
- plotly_extend_wrapper-1.4.0/plotly_extend_wrapper.egg-info/PKG-INFO +60 -0
- plotly_extend_wrapper-1.4.0/plotly_extend_wrapper.egg-info/SOURCES.txt +16 -0
- plotly_extend_wrapper-1.4.0/plotly_extend_wrapper.egg-info/dependency_links.txt +1 -0
- plotly_extend_wrapper-1.4.0/plotly_extend_wrapper.egg-info/requires.txt +10 -0
- plotly_extend_wrapper-1.4.0/plotly_extend_wrapper.egg-info/top_level.txt +1 -0
- plotly_extend_wrapper-1.4.0/pyproject.toml +33 -0
- plotly_extend_wrapper-1.4.0/setup.cfg +4 -0
- plotly_extend_wrapper-1.4.0/test/test_common.py +56 -0
- {plotly_extend_wrapper-1.2.0 → plotly_extend_wrapper-1.4.0}/test/test_updater.py +52 -1
- {plotly_extend_wrapper-1.2.0 → plotly_extend_wrapper-1.4.0}/test/test_wrapper.py +185 -0
- plotly_extend_wrapper-1.4.0/test/test_wrapper_polars.py +291 -0
- plotly_extend_wrapper-1.2.0/.devcontainer/devcontainer.json +0 -29
- plotly_extend_wrapper-1.2.0/.github/dependabot.yml +0 -12
- plotly_extend_wrapper-1.2.0/.github/workflows/deploy_pages.yaml +0 -34
- plotly_extend_wrapper-1.2.0/.github/workflows/pypi_release.yml +0 -29
- plotly_extend_wrapper-1.2.0/.github/workflows/unittest.yml +0 -26
- plotly_extend_wrapper-1.2.0/.gitignore +0 -159
- plotly_extend_wrapper-1.2.0/.python-version +0 -1
- plotly_extend_wrapper-1.2.0/.vscode/settings.json +0 -10
- plotly_extend_wrapper-1.2.0/codecov.yaml +0 -13
- plotly_extend_wrapper-1.2.0/docs/Makefile +0 -20
- plotly_extend_wrapper-1.2.0/docs/conf.py +0 -31
- plotly_extend_wrapper-1.2.0/docs/index.rst +0 -49
- plotly_extend_wrapper-1.2.0/docs/make.bat +0 -35
- plotly_extend_wrapper-1.2.0/docs/source/introduction.md +0 -1
- plotly_extend_wrapper-1.2.0/docs/source/wrapper.md +0 -49
- plotly_extend_wrapper-1.2.0/plotly_extend_wrapper/common.py +0 -12
- plotly_extend_wrapper-1.2.0/pyproject.toml +0 -41
- plotly_extend_wrapper-1.2.0/requirements-dev.lock +0 -266
- plotly_extend_wrapper-1.2.0/requirements.lock +0 -63
- plotly_extend_wrapper-1.2.0/test/test_common.py +0 -25
- {plotly_extend_wrapper-1.2.0 → plotly_extend_wrapper-1.4.0}/LICENSE +0 -0
- {plotly_extend_wrapper-1.2.0 → plotly_extend_wrapper-1.4.0}/plotly_extend_wrapper/updater.py +0 -0
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotly-extend-wrapper
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Author-email: Laplusdestiny <prayonshootingstars@gmail.com>
|
|
5
|
-
License-File: LICENSE
|
|
6
5
|
Requires-Python: >=3.9
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Requires-Dist: numpy>=1.24.0
|
|
10
|
-
Requires-Dist: pandas>=2.0.0
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
11
8
|
Requires-Dist: plotly>=5.12.0
|
|
9
|
+
Requires-Dist: kaleido>=0.2.1
|
|
12
10
|
Requires-Dist: pyarrow>=10.0.0
|
|
11
|
+
Requires-Dist: pandas>=2.0.0
|
|
13
12
|
Requires-Dist: scipy>=1.8.0
|
|
14
|
-
|
|
13
|
+
Requires-Dist: numpy>=1.24.0
|
|
14
|
+
Requires-Dist: nbformat>=4.2.0
|
|
15
|
+
Provides-Extra: polars
|
|
16
|
+
Requires-Dist: polars>=0.20.0; extra == "polars"
|
|
17
|
+
Dynamic: license-file
|
|
15
18
|
|
|
16
19
|
# plotly_extend_wrapper
|
|
17
20
|
|
|
@@ -20,10 +23,21 @@ Description-Content-Type: text/markdown
|
|
|
20
23
|
[](https://github.com/Laplusdestiny/plotly_extend_wrapper/releases)
|
|
21
24
|
[](https://pypi.org/project/plotly-extend-wrapper/)
|
|
22
25
|
|
|
23
|
-
|
|
24
26
|
Extended Python library for Plotly
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
- **Simple Interface**: Create complex visualizations with just a few lines of code
|
|
29
|
+
- **Pandas Integration**: Seamless integration with pandas DataFrames
|
|
30
|
+
- **Multiple Plot Types**: Support for various chart types including pie charts, sunburst diagrams, and 3D surfaces
|
|
31
|
+
- **Customization**: Easy plot customization through a unified interface
|
|
32
|
+
- **Automatic Layout**: Smart default settings for common plot configurations
|
|
33
|
+
|
|
34
|
+
For detailed documentation and examples, visit our [Documentation](https://laplusdestiny.github.io/plotly_extend_wrapper/)
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
``` bash
|
|
39
|
+
pip install plotly-extend-wrapper
|
|
40
|
+
```
|
|
27
41
|
|
|
28
42
|
## Requirement
|
|
29
43
|
|
|
@@ -33,17 +47,14 @@ You can make plot simply
|
|
|
33
47
|
- pandas >= 2.2.0
|
|
34
48
|
- scipy >= 1.12.0
|
|
35
49
|
|
|
36
|
-
## Graph
|
|
37
|
-
|
|
38
|
-
- Pie (`wrapper.Plot_pie`)
|
|
39
|
-
- Sunburst (`wrapper.Plot_sunburst`)
|
|
40
|
-
- Bubble (`wrapper.Plot_bubble_chart`)
|
|
41
|
-
- Line with secondary y-axis (`wrapper.Plot_line`)
|
|
42
|
-
- Bubble with linear line (`wrapper.Plot_bubble_with_line`)
|
|
43
|
-
- Surface (`wrapper.Plot_surface`)
|
|
44
|
-
|
|
45
|
-
|
|
46
50
|
## Issue
|
|
51
|
+
|
|
47
52
|
If there are some bugs, please make issue to tell me!
|
|
48
53
|
|
|
49
54
|
[](https://github.com/Laplusdestiny/plotly_extend_wrapper/issues)
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
MIT License
|
|
59
|
+
|
|
60
|
+
[](https://github.com/Laplusdestiny/plotly_extend_wrapper?tab=MIT-1-ov-file#MIT-1-ov-file)
|
|
@@ -5,10 +5,21 @@
|
|
|
5
5
|
[](https://github.com/Laplusdestiny/plotly_extend_wrapper/releases)
|
|
6
6
|
[](https://pypi.org/project/plotly-extend-wrapper/)
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
Extended Python library for Plotly
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
- **Simple Interface**: Create complex visualizations with just a few lines of code
|
|
11
|
+
- **Pandas Integration**: Seamless integration with pandas DataFrames
|
|
12
|
+
- **Multiple Plot Types**: Support for various chart types including pie charts, sunburst diagrams, and 3D surfaces
|
|
13
|
+
- **Customization**: Easy plot customization through a unified interface
|
|
14
|
+
- **Automatic Layout**: Smart default settings for common plot configurations
|
|
15
|
+
|
|
16
|
+
For detailed documentation and examples, visit our [Documentation](https://laplusdestiny.github.io/plotly_extend_wrapper/)
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
``` bash
|
|
21
|
+
pip install plotly-extend-wrapper
|
|
22
|
+
```
|
|
12
23
|
|
|
13
24
|
## Requirement
|
|
14
25
|
|
|
@@ -18,17 +29,14 @@ You can make plot simply
|
|
|
18
29
|
- pandas >= 2.2.0
|
|
19
30
|
- scipy >= 1.12.0
|
|
20
31
|
|
|
21
|
-
## Graph
|
|
22
|
-
|
|
23
|
-
- Pie (`wrapper.Plot_pie`)
|
|
24
|
-
- Sunburst (`wrapper.Plot_sunburst`)
|
|
25
|
-
- Bubble (`wrapper.Plot_bubble_chart`)
|
|
26
|
-
- Line with secondary y-axis (`wrapper.Plot_line`)
|
|
27
|
-
- Bubble with linear line (`wrapper.Plot_bubble_with_line`)
|
|
28
|
-
- Surface (`wrapper.Plot_surface`)
|
|
29
|
-
|
|
30
|
-
|
|
31
32
|
## Issue
|
|
33
|
+
|
|
32
34
|
If there are some bugs, please make issue to tell me!
|
|
33
35
|
|
|
34
36
|
[](https://github.com/Laplusdestiny/plotly_extend_wrapper/issues)
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
MIT License
|
|
41
|
+
|
|
42
|
+
[](https://github.com/Laplusdestiny/plotly_extend_wrapper?tab=MIT-1-ov-file#MIT-1-ov-file)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from plotly.io import get_chrome
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def check_directory(file_path):
|
|
6
|
+
"""
|
|
7
|
+
Ensures that the directory for the given file path exists, creating it if necessary.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
file_path (str or Path): The file path for which to check the directory.
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
Path: The resolved absolute path of the given file path.
|
|
14
|
+
"""
|
|
15
|
+
file_path = Path(file_path)
|
|
16
|
+
if not file_path.suffix:
|
|
17
|
+
dir_p = file_path
|
|
18
|
+
else:
|
|
19
|
+
dir_p = file_path.parent
|
|
20
|
+
if not dir_p.is_dir():
|
|
21
|
+
dir_p.mkdir(parents=True, exist_ok=True)
|
|
22
|
+
return file_path.resolve()
|
{plotly_extend_wrapper-1.2.0 → plotly_extend_wrapper-1.4.0}/plotly_extend_wrapper/wrapper.py
RENAMED
|
@@ -6,15 +6,52 @@ from plotly import graph_objects as go
|
|
|
6
6
|
from scipy.interpolate import griddata
|
|
7
7
|
import numpy as np
|
|
8
8
|
from copy import deepcopy
|
|
9
|
+
from typing import Union
|
|
9
10
|
|
|
11
|
+
# Optional polars support
|
|
12
|
+
try:
|
|
13
|
+
import polars as pl
|
|
14
|
+
POLARS_AVAILABLE = True
|
|
15
|
+
except ImportError:
|
|
16
|
+
POLARS_AVAILABLE = False
|
|
17
|
+
pl = None
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
|
|
20
|
+
def _normalize_dataframe(data) -> pd.DataFrame:
|
|
21
|
+
"""
|
|
22
|
+
Convert various DataFrame formats to pandas.DataFrame.
|
|
23
|
+
|
|
24
|
+
Supports pandas.DataFrame, polars.DataFrame, and polars.LazyFrame.
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
data : pd.DataFrame, pl.DataFrame, or pl.LazyFrame
|
|
29
|
+
Input data frame
|
|
30
|
+
|
|
31
|
+
Returns
|
|
32
|
+
-------
|
|
33
|
+
pd.DataFrame
|
|
34
|
+
Normalized pandas DataFrame
|
|
35
|
+
"""
|
|
36
|
+
if POLARS_AVAILABLE and pl is not None:
|
|
37
|
+
if isinstance(data, pl.LazyFrame):
|
|
38
|
+
return data.collect().to_pandas()
|
|
39
|
+
elif isinstance(data, pl.DataFrame):
|
|
40
|
+
return data.to_pandas()
|
|
41
|
+
|
|
42
|
+
if isinstance(data, pd.DataFrame):
|
|
43
|
+
return data
|
|
44
|
+
|
|
45
|
+
raise TypeError(f"Unsupported data type: {type(data)}. Expected pandas.DataFrame, polars.DataFrame, or polars.LazyFrame.")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def Plot_pie(data: Union[pd.DataFrame, "pl.DataFrame", "pl.LazyFrame"], target: str, **kwargs):
|
|
12
49
|
"""Make pie plot
|
|
13
50
|
|
|
14
51
|
Parameters
|
|
15
52
|
----------
|
|
16
|
-
data : pd.DataFrame
|
|
17
|
-
|
|
53
|
+
data : pd.DataFrame, pl.DataFrame, or pl.LazyFrame
|
|
54
|
+
DataFrame included data to make pie chart
|
|
18
55
|
target : str
|
|
19
56
|
String which column you would like to use for pie chart
|
|
20
57
|
|
|
@@ -23,17 +60,18 @@ def Plot_pie(data: pd.DataFrame, target: str, **kwargs):
|
|
|
23
60
|
plotly.graph_objects
|
|
24
61
|
Object of pie chart
|
|
25
62
|
"""
|
|
63
|
+
data = _normalize_dataframe(data)
|
|
26
64
|
vc = data[target].value_counts().reset_index(name="count")
|
|
27
65
|
return px.pie(vc, names=target, values="count", **kwargs)
|
|
28
66
|
|
|
29
67
|
|
|
30
|
-
def Plot_sunburst(data: pd.DataFrame, groups: list, **kwargs):
|
|
68
|
+
def Plot_sunburst(data: Union[pd.DataFrame, "pl.DataFrame", "pl.LazyFrame"], groups: list, **kwargs):
|
|
31
69
|
"""Make sunburst plot
|
|
32
70
|
|
|
33
71
|
Parameters
|
|
34
72
|
----------
|
|
35
|
-
data : pd.DataFrame
|
|
36
|
-
|
|
73
|
+
data : pd.DataFrame, pl.DataFrame, or pl.LazyFrame
|
|
74
|
+
DataFrame included data to make sunburst chart
|
|
37
75
|
groups : list
|
|
38
76
|
Strings list of group
|
|
39
77
|
Changed when you replace the order
|
|
@@ -43,6 +81,7 @@ def Plot_sunburst(data: pd.DataFrame, groups: list, **kwargs):
|
|
|
43
81
|
plotly.graph_objects
|
|
44
82
|
Object of sunburst chart
|
|
45
83
|
"""
|
|
84
|
+
data = _normalize_dataframe(data)
|
|
46
85
|
vc = data.value_counts(subset=groups).reset_index(name="count")
|
|
47
86
|
return px.sunburst(vc, path=groups, values="count", **kwargs)
|
|
48
87
|
|
|
@@ -69,8 +108,8 @@ class Plot_bubble_chart:
|
|
|
69
108
|
|
|
70
109
|
Parameters
|
|
71
110
|
----------
|
|
72
|
-
df : pandas.DataFrame
|
|
73
|
-
|
|
111
|
+
df : pandas.DataFrame, pl.DataFrame, or pl.LazyFrame
|
|
112
|
+
DataFrame included data to make plot
|
|
74
113
|
x : str
|
|
75
114
|
X-axis column's name
|
|
76
115
|
y : str
|
|
@@ -92,6 +131,7 @@ class Plot_bubble_chart:
|
|
|
92
131
|
offset : int, optional
|
|
93
132
|
Offset value for bubble size, by default 0
|
|
94
133
|
"""
|
|
134
|
+
df = _normalize_dataframe(df)
|
|
95
135
|
self.df = df.copy()
|
|
96
136
|
self.x = x
|
|
97
137
|
self.y = y
|
|
@@ -188,7 +228,7 @@ class Plot_bubble_chart:
|
|
|
188
228
|
|
|
189
229
|
|
|
190
230
|
def Plot_line(
|
|
191
|
-
df: pd.DataFrame,
|
|
231
|
+
df: Union[pd.DataFrame, "pl.DataFrame", "pl.LazyFrame"],
|
|
192
232
|
x: str,
|
|
193
233
|
y: list,
|
|
194
234
|
secondary_y: list,
|
|
@@ -198,6 +238,8 @@ def Plot_line(
|
|
|
198
238
|
save_html_path=None,
|
|
199
239
|
vspan=None,
|
|
200
240
|
vspan_color_randomize=False,
|
|
241
|
+
vline=None,
|
|
242
|
+
vline_color=None,
|
|
201
243
|
sort_column=True,
|
|
202
244
|
sort_x=True,
|
|
203
245
|
opacity=0.2,
|
|
@@ -208,7 +250,7 @@ def Plot_line(
|
|
|
208
250
|
|
|
209
251
|
Parameters
|
|
210
252
|
----------
|
|
211
|
-
df : pd.DataFrame
|
|
253
|
+
df : pd.DataFrame, pl.DataFrame, or pl.LazyFrame
|
|
212
254
|
Original dataframe
|
|
213
255
|
x : str
|
|
214
256
|
X-axis column name
|
|
@@ -228,6 +270,10 @@ def Plot_line(
|
|
|
228
270
|
Tuple list for filling color in specify period , by default None
|
|
229
271
|
vspan_color_randomize : bool, optional
|
|
230
272
|
If True, choose random color, by default False
|
|
273
|
+
vline : list, optional
|
|
274
|
+
List of timestamp to add vertical line, by default None
|
|
275
|
+
vline_color : str, optional
|
|
276
|
+
Color of vertical line, by default None
|
|
231
277
|
sort_column: boolean, optional
|
|
232
278
|
If True, sort y column list
|
|
233
279
|
sort_x: boolean, optional
|
|
@@ -246,6 +292,8 @@ def Plot_line(
|
|
|
246
292
|
|
|
247
293
|
random.seed(42)
|
|
248
294
|
|
|
295
|
+
df = _normalize_dataframe(df)
|
|
296
|
+
|
|
249
297
|
def pick_color():
|
|
250
298
|
return ["#" + "".join([random.choice("0123456789ABCDEF") for j in range(6)])][0]
|
|
251
299
|
|
|
@@ -301,6 +349,16 @@ def Plot_line(
|
|
|
301
349
|
line_width=0,
|
|
302
350
|
)
|
|
303
351
|
|
|
352
|
+
if vline is not None:
|
|
353
|
+
if not isinstance(vline, list):
|
|
354
|
+
vline = [vline]
|
|
355
|
+
|
|
356
|
+
if vline_color is None:
|
|
357
|
+
vline_color = pick_color()
|
|
358
|
+
|
|
359
|
+
for v in vline:
|
|
360
|
+
subfig.add_vline(x=v, line_color=vline_color)
|
|
361
|
+
|
|
304
362
|
if save_html_path is not None:
|
|
305
363
|
output_p = check_directory(save_html_path)
|
|
306
364
|
subfig.write_html(output_p)
|
|
@@ -386,7 +444,7 @@ def Plot_bubble_chart_with_line(
|
|
|
386
444
|
|
|
387
445
|
|
|
388
446
|
def Plot_surface(
|
|
389
|
-
df: pd.DataFrame,
|
|
447
|
+
df: Union[pd.DataFrame, "pl.DataFrame", "pl.LazyFrame"],
|
|
390
448
|
x: str,
|
|
391
449
|
y: str,
|
|
392
450
|
z: str,
|
|
@@ -398,6 +456,26 @@ def Plot_surface(
|
|
|
398
456
|
width=None,
|
|
399
457
|
**kwargs,
|
|
400
458
|
):
|
|
459
|
+
"""
|
|
460
|
+
Generates a 3D surface plot using Plotly.
|
|
461
|
+
|
|
462
|
+
Parameters:
|
|
463
|
+
df (pd.DataFrame, pl.DataFrame, or pl.LazyFrame): The input data frame containing the data to plot.
|
|
464
|
+
x (str): The column name for the x-axis.
|
|
465
|
+
y (str): The column name for the y-axis.
|
|
466
|
+
z (str): The column name for the z-axis.
|
|
467
|
+
fill_value (int, optional): The value to fill missing data in the pivot table. Default is 0.
|
|
468
|
+
smoothing (bool, optional): Whether to apply smoothing to the data. Default is False.
|
|
469
|
+
smooth_point_num (int, optional): The number of points to use for smoothing. Default is 100.
|
|
470
|
+
title (str, optional): The title of the plot. Default is None.
|
|
471
|
+
height (int, optional): The height of the plot. Default is None.
|
|
472
|
+
width (int, optional): The width of the plot. Default is None.
|
|
473
|
+
**kwargs: Additional keyword arguments to pass to the plot.
|
|
474
|
+
|
|
475
|
+
Returns:
|
|
476
|
+
plotly.graph_objs._figure.Figure: The generated 3D surface plot.
|
|
477
|
+
"""
|
|
478
|
+
|
|
401
479
|
def smooth_df(x: np.ndarray, y: np.ndarray, z: np.ndarray, num: int):
|
|
402
480
|
xi = np.linspace(x.min(), x.max(), num)
|
|
403
481
|
yi = np.linspace(y.min(), y.max(), num)
|
|
@@ -407,6 +485,8 @@ def Plot_surface(
|
|
|
407
485
|
zi = np.nan_to_num(zi)
|
|
408
486
|
return xi, yi, zi
|
|
409
487
|
|
|
488
|
+
df = _normalize_dataframe(df)
|
|
489
|
+
|
|
410
490
|
if smoothing:
|
|
411
491
|
X = df[x].values
|
|
412
492
|
Y = df[y].values
|
|
@@ -414,7 +494,8 @@ def Plot_surface(
|
|
|
414
494
|
X, Y, Z = smooth_df(X, Y, Z, smooth_point_num)
|
|
415
495
|
else:
|
|
416
496
|
pivot_df = pd.pivot_table(
|
|
417
|
-
df, index=x, columns=y, values=z, fill_value=fill_value
|
|
497
|
+
df, index=x, columns=y, values=z, fill_value=fill_value
|
|
498
|
+
)
|
|
418
499
|
|
|
419
500
|
X = pivot_df.columns.values
|
|
420
501
|
Y = pivot_df.index.values
|
|
@@ -424,7 +505,7 @@ def Plot_surface(
|
|
|
424
505
|
layout = go.Layout(
|
|
425
506
|
title=title,
|
|
426
507
|
scene=dict(
|
|
427
|
-
xaxis=dict(title=y),
|
|
508
|
+
xaxis=dict(title=y), # need to be replaced
|
|
428
509
|
yaxis=dict(title=x),
|
|
429
510
|
zaxis=dict(title=z),
|
|
430
511
|
),
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: plotly-extend-wrapper
|
|
3
|
+
Version: 1.4.0
|
|
4
|
+
Author-email: Laplusdestiny <prayonshootingstars@gmail.com>
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: plotly>=5.12.0
|
|
9
|
+
Requires-Dist: kaleido>=0.2.1
|
|
10
|
+
Requires-Dist: pyarrow>=10.0.0
|
|
11
|
+
Requires-Dist: pandas>=2.0.0
|
|
12
|
+
Requires-Dist: scipy>=1.8.0
|
|
13
|
+
Requires-Dist: numpy>=1.24.0
|
|
14
|
+
Requires-Dist: nbformat>=4.2.0
|
|
15
|
+
Provides-Extra: polars
|
|
16
|
+
Requires-Dist: polars>=0.20.0; extra == "polars"
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# plotly_extend_wrapper
|
|
20
|
+
|
|
21
|
+
[](https://github.com/Laplusdestiny/plotly_extend_wrapper/commits/main/)
|
|
22
|
+
[](https://app.codecov.io/gh/Laplusdestiny/plotly_extend_wrapper)
|
|
23
|
+
[](https://github.com/Laplusdestiny/plotly_extend_wrapper/releases)
|
|
24
|
+
[](https://pypi.org/project/plotly-extend-wrapper/)
|
|
25
|
+
|
|
26
|
+
Extended Python library for Plotly
|
|
27
|
+
|
|
28
|
+
- **Simple Interface**: Create complex visualizations with just a few lines of code
|
|
29
|
+
- **Pandas Integration**: Seamless integration with pandas DataFrames
|
|
30
|
+
- **Multiple Plot Types**: Support for various chart types including pie charts, sunburst diagrams, and 3D surfaces
|
|
31
|
+
- **Customization**: Easy plot customization through a unified interface
|
|
32
|
+
- **Automatic Layout**: Smart default settings for common plot configurations
|
|
33
|
+
|
|
34
|
+
For detailed documentation and examples, visit our [Documentation](https://laplusdestiny.github.io/plotly_extend_wrapper/)
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
``` bash
|
|
39
|
+
pip install plotly-extend-wrapper
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Requirement
|
|
43
|
+
|
|
44
|
+
- Python >= 3.9
|
|
45
|
+
- Plotly >= 5.0.0
|
|
46
|
+
- kaleido = 0.2.1
|
|
47
|
+
- pandas >= 2.2.0
|
|
48
|
+
- scipy >= 1.12.0
|
|
49
|
+
|
|
50
|
+
## Issue
|
|
51
|
+
|
|
52
|
+
If there are some bugs, please make issue to tell me!
|
|
53
|
+
|
|
54
|
+
[](https://github.com/Laplusdestiny/plotly_extend_wrapper/issues)
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
MIT License
|
|
59
|
+
|
|
60
|
+
[](https://github.com/Laplusdestiny/plotly_extend_wrapper?tab=MIT-1-ov-file#MIT-1-ov-file)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
plotly_extend_wrapper/__init__.py
|
|
5
|
+
plotly_extend_wrapper/common.py
|
|
6
|
+
plotly_extend_wrapper/updater.py
|
|
7
|
+
plotly_extend_wrapper/wrapper.py
|
|
8
|
+
plotly_extend_wrapper.egg-info/PKG-INFO
|
|
9
|
+
plotly_extend_wrapper.egg-info/SOURCES.txt
|
|
10
|
+
plotly_extend_wrapper.egg-info/dependency_links.txt
|
|
11
|
+
plotly_extend_wrapper.egg-info/requires.txt
|
|
12
|
+
plotly_extend_wrapper.egg-info/top_level.txt
|
|
13
|
+
test/test_common.py
|
|
14
|
+
test/test_updater.py
|
|
15
|
+
test/test_wrapper.py
|
|
16
|
+
test/test_wrapper_polars.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
plotly_extend_wrapper
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "plotly-extend-wrapper"
|
|
3
|
+
version = "1.4.0"
|
|
4
|
+
authors = [{ name = "Laplusdestiny", email = "prayonshootingstars@gmail.com" }]
|
|
5
|
+
dependencies = [
|
|
6
|
+
"plotly>=5.12.0",
|
|
7
|
+
"kaleido>=0.2.1",
|
|
8
|
+
"pyarrow>=10.0.0",
|
|
9
|
+
"pandas>=2.0.0",
|
|
10
|
+
"scipy>=1.8.0",
|
|
11
|
+
"numpy>=1.24.0",
|
|
12
|
+
"nbformat>=4.2.0",
|
|
13
|
+
]
|
|
14
|
+
readme = "README.md"
|
|
15
|
+
requires-python = ">= 3.9"
|
|
16
|
+
|
|
17
|
+
[project.optional-dependencies]
|
|
18
|
+
polars = ["polars>=0.20.0"]
|
|
19
|
+
|
|
20
|
+
[dependency-groups]
|
|
21
|
+
dev = [
|
|
22
|
+
"build>=1.4.0",
|
|
23
|
+
"furo>=2025.12.19",
|
|
24
|
+
"ipykernel>=6.31.0",
|
|
25
|
+
"myst-parser>=3.0.1",
|
|
26
|
+
"polars>=0.20.0",
|
|
27
|
+
"pytest>=8.4.2",
|
|
28
|
+
"pytest-cov>=7.0.0",
|
|
29
|
+
"scikit-learn>=1.6.1",
|
|
30
|
+
"sphinx>=7.4.7",
|
|
31
|
+
"twine>=6.2.0",
|
|
32
|
+
"wheel>=0.46.3",
|
|
33
|
+
]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
from plotly_extend_wrapper.common import check_directory
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_create_directory(tmp_path):
|
|
7
|
+
test_path = tmp_path / "test_dir/test_file.txt"
|
|
8
|
+
result = check_directory(test_path)
|
|
9
|
+
assert (tmp_path / "test_dir").is_dir()
|
|
10
|
+
assert result == test_path.resolve()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_existing_directory(tmp_path):
|
|
14
|
+
test_path = tmp_path / "existing_dir/test_file.txt"
|
|
15
|
+
(tmp_path / "existing_dir").mkdir(parents=True, exist_ok=True)
|
|
16
|
+
result = check_directory(test_path)
|
|
17
|
+
assert (tmp_path / "existing_dir").is_dir()
|
|
18
|
+
assert result == test_path.resolve()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_directory_path(tmp_path):
|
|
22
|
+
test_path = tmp_path / "new_dir"
|
|
23
|
+
result = check_directory(test_path)
|
|
24
|
+
assert test_path.is_dir()
|
|
25
|
+
assert result == test_path.resolve()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_check_directory_file_with_suffix(tmp_path):
|
|
29
|
+
"""Test check_directory with file path that has suffix"""
|
|
30
|
+
test_file = tmp_path / "subdir" / "test.txt"
|
|
31
|
+
result = check_directory(test_file)
|
|
32
|
+
|
|
33
|
+
# Directory should be created
|
|
34
|
+
assert test_file.parent.is_dir()
|
|
35
|
+
assert result == test_file.resolve()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_check_directory_nested_path(tmp_path):
|
|
39
|
+
"""Test check_directory with deeply nested path"""
|
|
40
|
+
test_path = tmp_path / "level1" / "level2" / "level3" / "file.csv"
|
|
41
|
+
result = check_directory(test_path)
|
|
42
|
+
|
|
43
|
+
# All directories should be created
|
|
44
|
+
assert test_path.parent.is_dir()
|
|
45
|
+
assert (tmp_path / "level1").is_dir()
|
|
46
|
+
assert (tmp_path / "level1" / "level2").is_dir()
|
|
47
|
+
assert result == test_path.resolve()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_check_directory_returns_absolute_path(tmp_path):
|
|
51
|
+
"""Test that check_directory returns absolute path"""
|
|
52
|
+
test_path = tmp_path / "test_dir"
|
|
53
|
+
result = check_directory(test_path)
|
|
54
|
+
|
|
55
|
+
assert result.is_absolute()
|
|
56
|
+
assert result == test_path.resolve()
|
|
@@ -103,4 +103,55 @@ def test_SetLegendPosition():
|
|
|
103
103
|
updater.update(legend_position="v")
|
|
104
104
|
new_plot = updater()
|
|
105
105
|
|
|
106
|
-
assert new_plot.layout.legend["orientation"] == "v"
|
|
106
|
+
assert new_plot.layout.legend["orientation"] == "v"
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def test_GetPlot():
|
|
110
|
+
plot = MakeTimeSeriesData()
|
|
111
|
+
updater = Update_plotly_object(plot)
|
|
112
|
+
result = updater.get_plot()
|
|
113
|
+
|
|
114
|
+
assert result is updater.po
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_UpdateWithLegendFalse():
|
|
118
|
+
"""Test that legend_position is not applied when legend is False"""
|
|
119
|
+
plot = MakeTimeSeriesData()
|
|
120
|
+
updater = Update_plotly_object(plot)
|
|
121
|
+
updater.update(legend=False, legend_position="h")
|
|
122
|
+
new_plot = updater()
|
|
123
|
+
|
|
124
|
+
# Should apply legend=False but not legend_position
|
|
125
|
+
assert new_plot.layout.showlegend == False
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_UpdateWithLegendTrue():
|
|
129
|
+
"""Test that legend_position is applied when legend is True"""
|
|
130
|
+
plot = MakeTimeSeriesData()
|
|
131
|
+
updater = Update_plotly_object(plot)
|
|
132
|
+
updater.update(legend=True, legend_position="h")
|
|
133
|
+
new_plot = updater()
|
|
134
|
+
|
|
135
|
+
assert new_plot.layout.showlegend == True
|
|
136
|
+
assert new_plot.layout.legend["orientation"] == "h"
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def test_UpdateNoneValues():
|
|
140
|
+
"""Test that None values don't update anything"""
|
|
141
|
+
plot = MakeTimeSeriesData()
|
|
142
|
+
original_height = plot.layout.height
|
|
143
|
+
original_width = plot.layout.width
|
|
144
|
+
|
|
145
|
+
updater = Update_plotly_object(plot)
|
|
146
|
+
updater.update(
|
|
147
|
+
xaxis_title=None,
|
|
148
|
+
yaxis_title=None,
|
|
149
|
+
height=None,
|
|
150
|
+
width=None,
|
|
151
|
+
marker_size=None,
|
|
152
|
+
)
|
|
153
|
+
new_plot = updater()
|
|
154
|
+
|
|
155
|
+
# Layout should remain unchanged for None values
|
|
156
|
+
assert new_plot.layout.height == original_height
|
|
157
|
+
assert new_plot.layout.width == original_width
|