aplotly 1.1.18__tar.gz → 1.1.20__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 (33) hide show
  1. {aplotly-1.1.18/aplotly.egg-info → aplotly-1.1.20}/PKG-INFO +3 -2
  2. {aplotly-1.1.18 → aplotly-1.1.20}/aplotly/colors.py +1 -1
  3. {aplotly-1.1.18 → aplotly-1.1.20}/aplotly/plots.py +140 -0
  4. {aplotly-1.1.18 → aplotly-1.1.20/aplotly.egg-info}/PKG-INFO +3 -2
  5. {aplotly-1.1.18 → aplotly-1.1.20}/aplotly.egg-info/SOURCES.txt +1 -0
  6. aplotly-1.1.20/examples/plot_lines_with_dist.py +14 -0
  7. {aplotly-1.1.18 → aplotly-1.1.20}/pyproject.toml +3 -2
  8. {aplotly-1.1.18 → aplotly-1.1.20}/LICENSE +0 -0
  9. {aplotly-1.1.18 → aplotly-1.1.20}/MANIFEST.in +0 -0
  10. {aplotly-1.1.18 → aplotly-1.1.20}/README.md +0 -0
  11. {aplotly-1.1.18 → aplotly-1.1.20}/aplotly/__init__.py +0 -0
  12. {aplotly-1.1.18 → aplotly-1.1.20}/aplotly/io.py +0 -0
  13. {aplotly-1.1.18 → aplotly-1.1.20}/aplotly/style.py +0 -0
  14. {aplotly-1.1.18 → aplotly-1.1.20}/aplotly/utils/return_breakdown.py +0 -0
  15. {aplotly-1.1.18 → aplotly-1.1.20}/aplotly.egg-info/dependency_links.txt +0 -0
  16. {aplotly-1.1.18 → aplotly-1.1.20}/aplotly.egg-info/requires.txt +0 -0
  17. {aplotly-1.1.18 → aplotly-1.1.20}/aplotly.egg-info/top_level.txt +0 -0
  18. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_bars.py +0 -0
  19. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_correlation.py +0 -0
  20. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_exposure_tree.py +0 -0
  21. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_gauge.py +0 -0
  22. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_line.py +0 -0
  23. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_line_and_save.py +0 -0
  24. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_lines.py +0 -0
  25. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_multiple_performance.py +0 -0
  26. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_performance.py +0 -0
  27. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_performance_by_trade.py +0 -0
  28. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_returns_breakdown.py +0 -0
  29. {aplotly-1.1.18 → aplotly-1.1.20}/examples/plot_returns_tree.py +0 -0
  30. {aplotly-1.1.18 → aplotly-1.1.20}/setup.cfg +0 -0
  31. {aplotly-1.1.18 → aplotly-1.1.20}/tests/test_colors.py +0 -0
  32. {aplotly-1.1.18 → aplotly-1.1.20}/tests/test_io.py +0 -0
  33. {aplotly-1.1.18 → aplotly-1.1.20}/tests/test_style.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: aplotly
3
- Version: 1.1.18
3
+ Version: 1.1.20
4
4
  License: MIT License
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
@@ -17,6 +17,7 @@ Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: plotly>=5.18.0
19
19
  Requires-Dist: pandas>=2.1.3
20
+ Dynamic: license-file
20
21
 
21
22
  # aplotly
22
23
 
@@ -88,7 +88,7 @@ def greys():
88
88
  def night():
89
89
  line_colors = {
90
90
  "green": "#00FF41",
91
- "grey": "#6E6E73",
91
+ # "grey": "#6E6E73",
92
92
  "white": "#F5F5F7",
93
93
  "red": "FF4500",
94
94
  "yellow": "FFD700",
@@ -169,6 +169,146 @@ def plot_multiple_lines(
169
169
  return fig
170
170
 
171
171
 
172
+ def plot_multiple_lines_with_distribution(
173
+ series: List[pd.Series],
174
+ ylabel: str,
175
+ xlabel: str,
176
+ labels: list = None,
177
+ visible: list = None,
178
+ styles: list = None,
179
+ legend: bool = True,
180
+ color_palette: str = "",
181
+ group_title: str = "",
182
+ plot_title: str = "",
183
+ hist_width: float = 0.2,
184
+ n_bins: int = 10,
185
+ ) -> go.Figure:
186
+ """Plot multiple line charts with a distribution histogram of final values.
187
+
188
+ Args:
189
+ series (List[pd.Series]): list of data for the line charts, the index is the x-axis and the values are the y-axis.
190
+ ylabel (str): y-axis label.
191
+ xlabel (str): x-axis label.
192
+ labels (list, optional): name of each line. Defaults to None (doesn't label of the lines).
193
+ visible (list, optional): if the lines should be visible by default. Defaults to None (all lines are visible).
194
+ styles (list, optional): list of line style dictionaries. Defaults to None.
195
+ legend (bool, optional): if the legend should be shown. Defaults to True.
196
+ color_palette (str, optional): name of the color palette to use. Defaults to "" (default color palette).
197
+ group_title (str, optional): name of the legend group. Defaults to "" (no group name).
198
+ plot_title (str, optional): title for the plot. Defaults to "" (no title).
199
+ hist_width (float, optional): relative width of histogram panel. Defaults to 0.2.
200
+ n_bins (int, optional): number of bins for the histogram. Defaults to 10.
201
+
202
+ Returns:
203
+ go.Figure: plotly figure containing the line charts and distribution histogram.
204
+ """
205
+ if labels is None:
206
+ labels = [None] * len(series)
207
+
208
+ if visible is None:
209
+ visible = [True] * len(series)
210
+
211
+ if styles is None:
212
+ styles = [{"width": 2}] * len(series)
213
+
214
+ if any(visible) is False:
215
+ legend = True
216
+
217
+ configure_plotly(subplots=1, color_palette=color_palette)
218
+
219
+ # Create subplot with shared y-axis
220
+ fig = make_subplots(
221
+ rows=1, cols=2, column_widths=[1 - hist_width, hist_width], shared_yaxes=True, horizontal_spacing=0.02
222
+ )
223
+
224
+ # Add line traces
225
+ final_values = []
226
+ for data, label, visibility, style in zip(series, labels, visible, styles):
227
+ fig.add_trace(
228
+ go.Scatter(
229
+ x=data.index,
230
+ y=data.values,
231
+ mode="lines",
232
+ name=label,
233
+ legendgroup=1,
234
+ legendgrouptitle_text=group_title,
235
+ visible=visibility,
236
+ line=style,
237
+ ),
238
+ row=1,
239
+ col=1,
240
+ )
241
+ if visibility:
242
+ final_values.append(data.iloc[-1])
243
+
244
+ # Calculate statistics
245
+ mean_val = sum(final_values) / len(final_values)
246
+ std_val = (sum((x - mean_val) ** 2 for x in final_values) / len(final_values)) ** 0.5
247
+
248
+ # Add single histogram trace for all final values
249
+ hist_trace = go.Histogram(
250
+ y=final_values,
251
+ name="Distribution",
252
+ legendgroup=1,
253
+ showlegend=False,
254
+ orientation="h",
255
+ nbinsy=n_bins,
256
+ marker_color="rgb(192, 192, 192)", # Light grey color
257
+ )
258
+ fig.add_trace(hist_trace, row=1, col=2)
259
+
260
+ # Calculate max count using numpy's histogram
261
+ import numpy as np
262
+
263
+ counts, _ = np.histogram(final_values, bins=n_bins)
264
+ max_count = max(counts)
265
+
266
+ # Add mean line with extended range
267
+ fig.add_trace(
268
+ go.Scatter(
269
+ x=[-0.1 * max_count, 1.1 * max_count],
270
+ y=[mean_val, mean_val],
271
+ mode="lines",
272
+ line=dict(color="black", width=2),
273
+ name="Mean",
274
+ showlegend=False,
275
+ ),
276
+ row=1,
277
+ col=2,
278
+ )
279
+
280
+ # Add std lines with extended range
281
+ for std_level in [mean_val - std_val, mean_val + std_val]:
282
+ fig.add_trace(
283
+ go.Scatter(
284
+ x=[-0.1 * max_count, 1.1 * max_count],
285
+ y=[std_level, std_level],
286
+ mode="lines",
287
+ line=dict(color="black", width=1, dash="dash"),
288
+ name="±1 std",
289
+ showlegend=False,
290
+ ),
291
+ row=1,
292
+ col=2,
293
+ )
294
+
295
+ # Update layout
296
+ fig.update_xaxes(title_text=xlabel, row=1, col=1)
297
+ fig.update_yaxes(title_text=ylabel, row=1, col=1)
298
+ fig.update_xaxes(title_text="Count", row=1, col=2)
299
+ fig.update_layout(
300
+ showlegend=legend,
301
+ title_text=plot_title,
302
+ bargap=0, # Remove gaps between bars
303
+ bargroupgap=0, # Remove gaps between groups
304
+ )
305
+
306
+ # Set x-axis range for histogram panel
307
+ fig.update_xaxes(range=[0, max_count], row=1, col=2)
308
+
309
+ return fig
310
+
311
+
172
312
  def plot_performance(
173
313
  performance: pd.Series,
174
314
  drawdown: pd.Series,
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: aplotly
3
- Version: 1.1.18
3
+ Version: 1.1.20
4
4
  License: MIT License
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
@@ -17,6 +17,7 @@ Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: plotly>=5.18.0
19
19
  Requires-Dist: pandas>=2.1.3
20
+ Dynamic: license-file
20
21
 
21
22
  # aplotly
22
23
 
@@ -20,6 +20,7 @@ examples/plot_gauge.py
20
20
  examples/plot_line.py
21
21
  examples/plot_line_and_save.py
22
22
  examples/plot_lines.py
23
+ examples/plot_lines_with_dist.py
23
24
  examples/plot_multiple_performance.py
24
25
  examples/plot_performance.py
25
26
  examples/plot_performance_by_trade.py
@@ -0,0 +1,14 @@
1
+ import numpy as np
2
+ import pandas as pd
3
+
4
+ from aplotly.plots import plot_multiple_lines_with_distribution
5
+
6
+ fig = plot_multiple_lines_with_distribution(
7
+ [pd.Series(np.random.rand(100), index=np.arange(100)) for _ in range(100)],
8
+ labels=[f"Test {i}" for i in range(100)],
9
+ styles=[{"shape": "hv"} for _ in range(100)],
10
+ xlabel="X",
11
+ ylabel="Y",
12
+ hist_width=0.2,
13
+ )
14
+ fig.show()
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "aplotly"
7
- version = "1.1.18"
7
+ version = "1.1.20"
8
8
  readme = "README.md"
9
9
  license = { file = "LICENSE" }
10
10
  classifiers = [
@@ -19,12 +19,13 @@ dependencies = [
19
19
  requires-python = ">=3.10"
20
20
 
21
21
  [tool.bumpver]
22
- current_version = "1.1.18"
22
+ current_version = "1.1.20"
23
23
  version_pattern = "MAJOR.MINOR.PATCH"
24
24
  commit_message = "Bump version {old_version} -> {new_version}"
25
25
  commit = true
26
26
  tag = true
27
27
  push = false
28
28
 
29
+
29
30
  [tool.bumpver.file_patterns]
30
31
  "pyproject.toml" = ['current_version = "{version}"', 'version = "{version}"']
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes