plotguy 2.2.4__tar.gz → 2.3.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotguy
3
- Version: 2.2.4
3
+ Version: 2.3.1
4
4
  Summary: Plotguy
5
5
  Home-page: https://pypi.org/project/plotguy/
6
6
  Author: Plotguy Team
@@ -1,5 +1,6 @@
1
1
  import warnings
2
2
  warnings.simplefilter("ignore", UserWarning)
3
+ #warnings.simplefilter("ignore", RuntimeWarning)
3
4
 
4
5
  import datetime
5
6
  import os
@@ -12,6 +13,7 @@ import requests
12
13
  import pandas as pd
13
14
  import numpy as np
14
15
  import io
16
+ import re
15
17
 
16
18
  from .equity_curves import *
17
19
  from .signals import *
@@ -22,6 +24,24 @@ from bs4 import BeautifulSoup
22
24
 
23
25
  def get_all_para_combination(para_dict, backtest_attribute, df_dict, sec_profile, manager_list, count_down=False):
24
26
 
27
+ key_to_keep = ['start_date',
28
+ 'end_date',
29
+ 'freq',
30
+ 'market',
31
+ 'sectype',
32
+ 'initial_capital',
33
+ 'data_folder',
34
+ 'equity_curve_folder',
35
+ 'secondary_data_folder',
36
+ 'backtest_name',
37
+ 'default_market_price',
38
+ 'summary_mode']
39
+
40
+ for k in backtest_attribute.copy().keys():
41
+ if k not in key_to_keep:
42
+ del backtest_attribute[k]
43
+
44
+
25
45
  risk_free_rate = get_risk_free_rate(backtest_attribute['start_date'], backtest_attribute['end_date'])
26
46
 
27
47
  freq = backtest_attribute['freq']
@@ -135,6 +155,8 @@ def save_backtest_result(df, para_combination_item):
135
155
  ### for intraday ###
136
156
  if intraday:
137
157
  df_daily = df.resample('D').agg({'price': agg_price})
158
+ #df_daily = df.resample('D').agg({'price': agg_price, 'equity_value': agg_price})
159
+ df_daily = df_daily[df_daily['price'].notna()]
138
160
  else:
139
161
  df_daily = df
140
162
 
@@ -196,6 +218,7 @@ def save_backtest_result(df, para_combination_item):
196
218
  yearly_stats_string += f'{year},year_trade_count:0.00,year_win_rate:00.00,year_return:-00.00|'
197
219
 
198
220
  yearly_stats_string = yearly_stats_string[:-1]
221
+ correlation = 0
199
222
 
200
223
  elif len(df_count) > 0:
201
224
 
@@ -277,8 +300,11 @@ def save_backtest_result(df, para_combination_item):
277
300
  equity_net_profit = df.at[df.index[-1], 'equity_value'] - df.at[df.index[0], 'equity_value']
278
301
 
279
302
  equity_return_on_capital = equity_net_profit / df.at[df.index[0], 'equity_value']
280
- equity_annualized_return = (np.sign(1 + equity_return_on_capital) * np.abs(1 + equity_return_on_capital)) ** (
281
- 365 / holding_period_day) - 1
303
+ if 1 + equity_return_on_capital > 0:
304
+ equity_annualized_return = (np.sign(1 + equity_return_on_capital) * np.abs(1 + equity_return_on_capital)) ** (365 / holding_period_day) - 1
305
+ else:
306
+ equity_annualized_return = -1
307
+
282
308
  equity_annualized_std = equity_pct_series.std() * math.sqrt(365)
283
309
  equity_annualized_sr = (
284
310
  equity_annualized_return - risk_free_rate / 100) / equity_annualized_std if equity_annualized_std != 0 else 0
@@ -290,8 +316,14 @@ def save_backtest_result(df, para_combination_item):
290
316
  equity_annualized_sr = round(equity_annualized_sr, 2)
291
317
  equity_net_profit_to_mdd = round(100 * equity_net_profit_to_mdd, 2)
292
318
 
319
+ df['equity_return'] = df['equity_value'].pct_change() * 100
320
+ df['price_return'] = df['price'].pct_change() * 100
321
+
322
+ correlation = df['equity_return'].corr(df['price_return'])
323
+
293
324
  if long_short == 'short':
294
325
  return_on_capital_diff = equity_annualized_return - (-1) * price_annualized_return
326
+ correlation *= -1
295
327
  else:
296
328
  ### consider both long and long_short ###
297
329
  return_on_capital_diff = equity_annualized_return - price_annualized_return
@@ -311,6 +343,7 @@ def save_backtest_result(df, para_combination_item):
311
343
  cov_return = round(cov_return, 2)
312
344
  cov_count = round(cov_count, 2)
313
345
  total_commission = int(round(total_commission))
346
+ correlation = round(correlation, 3)
314
347
 
315
348
  backtest_result_dict = {
316
349
  'ref_code': ref_code,
@@ -342,6 +375,7 @@ def save_backtest_result(df, para_combination_item):
342
375
  'yearly_stats_string': yearly_stats_string,
343
376
  'cov_return': cov_return,
344
377
  'cov_count': cov_count,
378
+ 'correlation': correlation,
345
379
  'total_commission': total_commission
346
380
  }
347
381
 
@@ -384,16 +418,40 @@ def get_risk_free_rate(start_date, end_date):
384
418
  # return app
385
419
 
386
420
 
387
- def plot(mode, backtest_result_df = None, number_of_curves=20):
421
+ def plot(mode, backtest_result_df = None, number_of_curves=20, filter_list= []):
388
422
 
389
423
  if mode == 'equity_curves':
390
- app = equity_curves.Plot(backtest_result_df, number_of_curves)
424
+ if len(filter_list) > 0: filter_list = convert_filter_list(filter_list)
425
+ app = equity_curves.Plot(backtest_result_df, number_of_curves, filter_list)
391
426
 
392
427
  if mode == 'aggregate':
393
428
  app = aggregate.Aggregate()
394
429
 
395
430
  return app
396
431
 
432
+ def convert_filter_list(filter_list):
433
+ '''
434
+ filter string as follows
435
+ equity_return_on_capital eg: 50% --> 50
436
+ equity_annualized_return eg: 50% --> 50
437
+ return_on_capital_diff eg: 50% --> 50
438
+ equity_annualized_sr eg: 0.9
439
+ equity_mdd_pct eg: 50% --> 50
440
+ num_of_trade eg: 10
441
+ cov_count eg: 1
442
+ cov_return eg: 1
443
+ correlation eg: 0.5
444
+ win_rate eg: 50% --> 50
445
+ '''
446
+
447
+ for i in range(len(filter_list)):
448
+ filter = filter_list[i]
449
+ pattern = r'([a-zA-Z_]+)([<>=]+)(-?\d+\.?\d*)'
450
+ match = re.match(pattern, filter)
451
+
452
+ filter_list[i] = [match.group(1), match.group(2), match.group(3)]
453
+
454
+ return filter_list
397
455
 
398
456
  def get_latest_fed_fund_rate():
399
457
  url = "https://fred.stlouisfed.org/series/FEDFUNDS"
@@ -260,7 +260,7 @@ class Aggregate:
260
260
 
261
261
  df_current = pd.DataFrame()
262
262
 
263
- df_current[f'{row['folder']}_{row['backtest_name']}_{i}'] = df['equity_value']
263
+ df_current[f'{row["folder"]}_{row["backtest_name"]}_{i}'] = df["equity_value"]
264
264
  df_current.index = df.index
265
265
  df_list.append(df_current.copy())
266
266
 
@@ -35,7 +35,6 @@ class Components:
35
35
  children=dbc.Select(id='filter_name',
36
36
  placeholder="Select Filter",
37
37
  options=[
38
- {'label': 'Exclude Stock', 'value': 'exclude'},
39
38
  {'label': 'Return on Capital >', 'value': 'equity_return_on_capital>'},
40
39
  {'label': 'Return on Capital <', 'value': 'equity_return_on_capital<'},
41
40
  {'label': 'Annualized Return >', 'value': 'equity_annualized_return>'},
@@ -52,6 +51,8 @@ class Components:
52
51
  {'label': 'COV (Count) <', 'value': 'cov_count<'},
53
52
  {'label': 'COV (Return) >', 'value': 'cov_return>'},
54
53
  {'label': 'COV (Return) <', 'value': 'cov_return<'},
54
+ {'label': 'Correlation <', 'value': 'correlation<'},
55
+ {'label': 'Correlation >', 'value': 'correlation>'},
55
56
  {'label': 'Win Rate >', 'value': 'win_rate>'},
56
57
  {'label': 'Win Rate <', 'value': 'win_rate<'},
57
58
  ],
@@ -176,79 +177,6 @@ class Components:
176
177
 
177
178
  return checkbox_div, code_list
178
179
 
179
- def update_stat_div(self, period, pct_mean, rise_mean, fall_mean):
180
- div = html.Div([
181
-
182
- dbc.Row([
183
- dbc.Col(width=2),
184
- dbc.Col(str(period[0]) + ' Days', width=2),
185
- dbc.Col(str(period[1]) + ' Days', width=2),
186
- dbc.Col(str(period[2]) + ' Days', width=2),
187
- dbc.Col(str(period[3]) + ' Days', width=2),
188
- dbc.Col(str(period[4]) + ' Days', width=2),
189
- ]),
190
-
191
- dbc.Row([
192
- dbc.Col('pct_change', width=2),
193
- dbc.Col(f'{pct_mean[0]}%', width=2),
194
- dbc.Col(f'{pct_mean[1]}%', width=2),
195
- dbc.Col(f'{pct_mean[2]}%', width=2),
196
- dbc.Col(f'{pct_mean[3]}%', width=2),
197
- dbc.Col(f'{pct_mean[4]}%', width=2),
198
- ]),
199
-
200
- dbc.Row([
201
- dbc.Col('max_rise', width=2),
202
- dbc.Col(f'{rise_mean[0]}%', width=2),
203
- dbc.Col(f'{rise_mean[1]}%', width=2),
204
- dbc.Col(f'{rise_mean[2]}%', width=2),
205
- dbc.Col(f'{rise_mean[3]}%', width=2),
206
- dbc.Col(f'{rise_mean[4]}%', width=2),
207
- ]),
208
-
209
- dbc.Row([
210
- dbc.Col('max_fall', width=2),
211
- dbc.Col(f'{fall_mean[0]}%', width=2),
212
- dbc.Col(f'{fall_mean[1]}%', width=2),
213
- dbc.Col(f'{fall_mean[2]}%', width=2),
214
- dbc.Col(f'{fall_mean[3]}%', width=2),
215
- dbc.Col(f'{fall_mean[4]}%', width=2),
216
- ]),
217
-
218
- ])
219
-
220
- return div
221
-
222
- def generate_radioitems(self, para_dict):
223
- radioitems_div = []
224
-
225
- for i, key in enumerate(para_dict):
226
- options = para_dict[key]
227
-
228
- radioitems_div.append(html.Div(key,style={'color': 'Yellow','font-size': '14px'}))
229
-
230
- radioitems_div.append(dcc.RadioItems(
231
- id={'type': 'para_radioitems', 'index': i},
232
- options=[{'label': k,
233
- 'value': k} for k in options],
234
- labelStyle={'font-size': '13px'},
235
- inputStyle={'margin-left': '10px', 'margin-right': '5px'}
236
-
237
- ), )
238
-
239
- radioitems_div.append(html.Div(html.Img(),style={'height':'10px'}))
240
-
241
- return radioitems_div
242
-
243
- def selection_title(self, para_dict, values):
244
- title = []
245
- for i, key in enumerate(para_dict):
246
- title.append(dbc.Row(
247
- [dbc.Col(key, width=6),
248
- dbc.Col(f'{values[i]}', style={'text-align': 'center'}, width=6)]))
249
-
250
- return title
251
-
252
180
  def update_performance_matrix(self, init_chart, para_keys_list, result_df, line_selected = 0):
253
181
 
254
182
  if init_chart:
@@ -258,8 +186,6 @@ class Components:
258
186
  ref_code = result_df.loc[line_selected].ref_code
259
187
 
260
188
  yearly_stats_string = result_df.loc[line_selected]['yearly_stats_string']
261
- print(result_df)
262
- print(yearly_stats_string)
263
189
 
264
190
  per_col1 =[]
265
191
  per_col2 = []
@@ -270,6 +196,7 @@ class Components:
270
196
  per_col_2_3 = [html.Div('BaH',style={'text-align': 'center', 'font-weight': 'bold', 'color':'yellow'})]
271
197
 
272
198
  keys = ['num_of_trade',
199
+ 'correlation',
273
200
  'equity_net_profit',
274
201
  'equity_net_profit_to_mdd',
275
202
  'return_on_capital_diff',
@@ -330,39 +257,57 @@ class Components:
330
257
 
331
258
  result_df['risk_free_rate'] = result_df['risk_free_rate'].apply(lambda x: f"{x:.2f} %")
332
259
 
260
+ div_padding = '5px'
261
+
333
262
  per_col_1_1.append(html.Div('Number of Trade', style={'background-color': 'darkblue' }))
334
- per_col_1_1.append(html.Div('Net Profit'))
335
- per_col_1_1.append(html.Div('Net Profit/MDD', style={'background-color': 'darkblue' }))
336
- per_col_1_1.append(html.Div('Return-BaH % Diff.'))
337
- per_col_1_1.append(html.Div('Win Rate', style={'background-color': 'darkblue' }))
338
- per_col_1_1.append(html.Div('COV (Count)'))
339
- per_col_1_1.append(html.Div('COV (Return)', style={'background-color': 'darkblue' }))
340
- per_col_1_1.append(html.Div('Total Commission'))
341
- per_col_1_1.append(html.Div('Risk Free Rate', style={'background-color': 'darkblue' }))
342
-
343
- per_col_2_1.append(html.Div('Return on Capital'))
344
- per_col_2_1.append(html.Div('Ann. Return', style={'background-color': 'darkblue' }))
345
- per_col_2_1.append(html.Div('Ann. Std'))
346
- per_col_2_1.append(html.Div('Ann. Sharpe Ratio', style={'background-color': 'darkblue' }))
347
- per_col_2_1.append(html.Div('MDD Dollar'))
348
- per_col_2_1.append(html.Div('MDD Percentage', style={'background-color': 'darkblue' }))
349
-
350
- for i in range(9):
263
+ per_col_1_1.append(html.Div('Correlation'))
264
+ per_col_1_1.append(html.Div(style={'height': div_padding}))
265
+
266
+ per_col_1_1.append(html.Div('Net Profit', style={'background-color': 'darkblue' }))
267
+ per_col_1_1.append(html.Div('Net Profit/MDD'))
268
+ per_col_1_1.append(html.Div(style={'height': div_padding}))
269
+
270
+ per_col_1_1.append(html.Div('Return-BaH % Diff.', style={'background-color': 'darkblue' }))
271
+ per_col_1_1.append(html.Div('Win Rate'))
272
+ per_col_1_1.append(html.Div(style={'height': div_padding}))
273
+
274
+ per_col_1_1.append(html.Div('COV (Count)', style={'background-color': 'darkblue' }))
275
+ per_col_1_1.append(html.Div('COV (Return)'))
276
+ per_col_1_1.append(html.Div(style={'height': div_padding}))
277
+
278
+ per_col_1_1.append(html.Div('Total Commission', style={'background-color': 'darkblue' }))
279
+ per_col_1_1.append(html.Div('Risk Free Rate'))
280
+
281
+ per_col_2_1.append(html.Div('Return on Capital', style={'background-color': 'darkblue' }))
282
+ per_col_2_1.append(html.Div('Ann. Return'))
283
+ per_col_2_1.append(html.Div(style={'height': div_padding}))
284
+ per_col_2_1.append(html.Div('Ann. Std', style={'background-color': 'darkblue' }))
285
+ per_col_2_1.append(html.Div('Ann. Sharpe Ratio'))
286
+ per_col_2_1.append(html.Div(style={'height': div_padding}))
287
+ per_col_2_1.append(html.Div('MDD Dollar', style={'background-color': 'darkblue' }))
288
+ per_col_2_1.append(html.Div('MDD Percentage'))
289
+
290
+ for i in range(10):
351
291
  content = result_df.iloc[0][keys[i]]
352
292
  if i%2 == 1:
353
293
  per_col_1_2.append(html.Div(content, style={'text-align': 'center', }))
294
+ per_col_1_2.append(html.Div(style={'height': div_padding}))
354
295
  else:
355
- per_col_1_2.append(html.Div(content, style={'text-align': 'center','background-color': 'darkblue' }))
356
- for i in range(9, 15):
296
+ per_col_1_2.append(html.Div(content, style={'text-align': 'center', 'background-color': 'darkblue'}))
297
+
298
+ for i in range(10, 16):
357
299
  content = result_df.iloc[0][keys[i]]
358
300
  if i%2 == 1:
359
301
  per_col_2_2.append(html.Div(content, style={'text-align': 'center'}),)
302
+ per_col_2_2.append(html.Div(style={'height': div_padding}))
360
303
  else:
361
304
  per_col_2_2.append(html.Div(content, style={'text-align': 'center', 'background-color': 'darkblue'}),)
362
- for i in range(15, 21):
305
+
306
+ for i in range(16, 22):
363
307
  content = result_df.iloc[0][keys[i]]
364
308
  if i%2 == 1:
365
309
  per_col_2_3.append(html.Div(content, style={'text-align': 'center'}))
310
+ per_col_2_3.append(html.Div(style={'height': div_padding}))
366
311
  else:
367
312
  per_col_2_3.append(html.Div(content, style={'text-align': 'center', 'background-color': 'darkblue'}))
368
313
 
@@ -443,12 +388,12 @@ class Components:
443
388
  for idx , key in enumerate(para_keys_list):
444
389
  if idx%2 == 0:
445
390
  title.append(dbc.Row(
446
- [dbc.Col(key,width=6),
447
- dbc.Col(f'{result_df.iloc[0][key]}',style={ 'text-align': 'center'},width=6)]))
391
+ [dbc.Col(key,width=6, style={ 'background-color': 'darkblue', 'marginBottom': '6px'}),
392
+ dbc.Col(f'{result_df.iloc[0][key]}',style={ 'text-align': 'center', 'marginBottom': '6px', 'background-color': 'darkblue'},width=6)]))
448
393
  else:
449
394
  title.append(dbc.Row(
450
- [dbc.Col(key,width=6, style={ 'background-color': 'darkblue'}),
451
- dbc.Col(f'{result_df.iloc[0][key]}',style={ 'text-align': 'center', 'background-color': 'darkblue'},width=6)]))
395
+ [dbc.Col(key,width=6),
396
+ dbc.Col(f'{result_df.iloc[0][key]}',style={ 'text-align': 'center'},width=6)]))
452
397
 
453
398
  matrix_div = html.Div([
454
399
  html.Div(style={'height': '8px', }),
@@ -457,6 +402,8 @@ class Components:
457
402
  html.Div('Selected Curve', style={'color': 'Cyan',
458
403
  'display': 'inline',
459
404
  'font-size': '15px'}),
405
+ html.Div(style={'height': '1px', }),
406
+
460
407
  html.Div('', id='save_status',
461
408
  style={'color': 'Cyan',
462
409
  'display': 'inline',
@@ -469,10 +416,12 @@ class Components:
469
416
  html.Div(style={'height': '15px', }),
470
417
 
471
418
  html.Div('Performance', style={'color': 'Cyan', 'font-size': '15px'}),
419
+ html.Div(style={'height': '2px', }),
472
420
  html.Div(children=per_col1, style={'font-size': '11px','padding-left':'1px'}),
473
421
  html.Div(style={'height': '15px', }),
474
422
 
475
423
  html.Div('Comparison', style={'color': 'Cyan', 'font-size': '15px'}),
424
+ html.Div(style={'height': '1px', }),
476
425
  html.Div(children=per_col2, style={'font-size': '11px','padding-right': '10px','padding-left':'1px'}),
477
426
  html.Div(style={'height': '15px', }),
478
427
 
@@ -507,6 +456,7 @@ class Components:
507
456
  'cov_return': 'COV (Return)',
508
457
  'win_rate':'Win Rate',
509
458
  'return_on_capital_diff': 'Return/BnH % Diff.',
459
+ 'correlation': 'Correlation',
510
460
  #'exclude': 'Exclude',
511
461
  }
512
462
 
@@ -558,12 +508,11 @@ class Components:
558
508
  return df_checked
559
509
 
560
510
  def assign_colour(self, profile, degree):
561
- if profile == 0: rgb = (0, int(252 - 252 * degree), 252)
511
+ if profile == 0: rgb = (0, int(252 - 252 * degree), 0)
562
512
  elif profile == 1: rgb = (int(252 - 252 * degree), 252, 0)
563
- elif profile == 2: rgb = (252, 0, int(252 - 252 * degree))
564
- elif profile == 3: rgb = (0, 252, int(252 * degree))
565
- elif profile == 4: rgb = (252, int(252 * degree), 0)
566
- elif profile == 5: rgb = (int(252 * degree), 0, 252)
513
+ elif profile == 2: rgb = (252, 0, int(round((252 - 252 * degree)/3)))
514
+ elif profile == 3: rgb = (0, 252, int(round((252 - 252 * degree)/3)))
515
+ elif profile >= 4: rgb = (252, int(252 * degree), 0)
567
516
  return 'rgb' + str(rgb)
568
517
 
569
518
  def generate_main_chart(self, graph_df, backtest_name, equity_curve_folder, para_keys_list):
@@ -767,28 +716,6 @@ class Components:
767
716
 
768
717
  return fig_line
769
718
 
770
- ### for class signal ###
771
- def generate_df_stat(self, df, period):
772
- col_pct = 'pct_change_' + str(period)
773
- col_rise = 'max_rise_' + str(period)
774
- col_fall = 'max_fall_' + str(period)
775
- df_his = df.copy()
776
- df_his[col_pct] = df_his['close'].pct_change(period)
777
- df_his[col_pct] = df_his[col_pct].shift(-1 * period)
778
- df_his[col_pct] = df_his[col_pct] * 100
779
- df_his[col_pct] = df_his[col_pct].map(lambda x: round(x, 2))
780
- df_his[col_rise] = (df_his['high'].rolling(period).max().shift(-1 * (period)) / df_his['close']) - 1
781
- df_his[col_fall] = (df_his['low'].rolling(period).min().shift(-1 * (period)) / df_his['close']) - 1
782
-
783
- df_his = df_his[df_his['logic'] == 'trade_logic']
784
-
785
- df_his[col_rise] = df_his[col_rise] * 100
786
- df_his[col_fall] = df_his[col_fall] * 100
787
-
788
- df_his[col_rise] = df_his[col_rise].map(lambda x: round(x, 2))
789
- df_his[col_fall] = df_his[col_fall].map(lambda x: round(x, 2))
790
-
791
- return round(df_his[col_pct].mean(), 2), round(df_his[col_rise].mean(), 2), round(df_his[col_fall].mean(), 2)
792
719
 
793
720
  def aggregate_df(self):
794
721
  all_str_dir = []
@@ -13,7 +13,7 @@ import os
13
13
 
14
14
  class Plot:
15
15
 
16
- filter_list = []
16
+ #filter_list = []
17
17
  add_filter_btn_count = 0
18
18
  main_chart_btn_clicks = 0
19
19
  stra_alys_chart_btn_clicks = 0
@@ -24,7 +24,7 @@ class Plot:
24
24
  select_all_status = False
25
25
 
26
26
 
27
- def __new__(self, backtest_result_df, number_of_curves):
27
+ def __new__(self, backtest_result_df, number_of_curves, filter_list= []):
28
28
 
29
29
  self.chart_bg = '#1f2c56'
30
30
  self.init_chart = True
@@ -49,6 +49,9 @@ class Plot:
49
49
  para_keys_str = self.backtest_result_dict[self.backtest_result_key[0]]['para_keys_str']
50
50
  self.para_keys_list = para_keys_str.split('|')
51
51
 
52
+ self.filter_list = filter_list
53
+ self.init_filter = True if len(self.filter_list) >0 else False
54
+
52
55
  components = Components(number_of_curves)
53
56
 
54
57
  self.start_year = datetime.datetime.strptime(self.start_date, '%Y-%m-%d').year
@@ -116,7 +119,7 @@ class Plot:
116
119
  dbc.Col(html.Div([
117
120
  html.Div(style={'height': '15px', }),
118
121
  html.Div('Sorting Method', style={'color': 'Cyan', 'margin-left': '15px', 'font-size': '15px'}),
119
- html.Div(style={'height': '10px', }),
122
+ html.Div(style={'height': '22px', }),
120
123
  sort_method_dropdown,
121
124
  html.Div(style={'height': '15px', }),
122
125
  html.Div('Parameters', style={'color': 'Cyan', 'margin-left': '15px', 'font-size': '15px'}),
@@ -247,7 +250,7 @@ class Plot:
247
250
  if not add_filter_btn_clicks:
248
251
  if not main_chart_btn_click:
249
252
  #self.sort_method_current = sort_method
250
- self.filter_list = []
253
+ #self.filter_list = []
251
254
  self.add_filter_btn_count = 0
252
255
  self.stra_alys_chart_btn_clicks = 0
253
256
  self.save_clicks = 0
@@ -258,25 +261,27 @@ class Plot:
258
261
  filter_input_div = filter_input
259
262
 
260
263
  ######################################################################
264
+ ########################### filter reaction ##########################
261
265
 
262
- if add_filter_btn_clicks:
263
- if add_filter_btn_clicks > self.add_filter_btn_count: ## Add btn Pressed
264
- self.add_filter_btn_count = add_filter_btn_clicks
265
- if filter_name:
266
- if filter_input_value:
267
- if filter_name == 'exclude':
268
- self.filter_list.append(['exclude', ' ', filter_input_value])
269
- else:
270
- self.filter_list.append([filter_name[0:-1], filter_name[-1], filter_input_value])
271
- filter_div = components.update_filter_div(self.filter_list)
272
- if len(self.filter_list) > 11:
273
- filter_dropdown_div = filter_dropdown_disabled
274
- filter_input_div = filter_input_disabled
275
- _add_filter_save_btn_style = add_filter_save_btn_style_disabled
276
- else:
277
- filter_dropdown_div = filter_dropdown
278
- filter_input_div = filter_input
279
- self.init_chart = False
266
+ if add_filter_btn_clicks != None and self.add_filter_btn_count!= None:
267
+ add_filter_btn_clicked = add_filter_btn_clicks > self.add_filter_btn_count
268
+ else:
269
+ add_filter_btn_clicked = False
270
+
271
+ if add_filter_btn_clicked or self.init_filter: ## Add btn Pressed
272
+ if not self.init_filter: self.add_filter_btn_count = add_filter_btn_clicks
273
+ if (filter_name != None and filter_input_value != None) or self.init_filter:
274
+ if not self.init_filter: self.filter_list.append([filter_name[0:-1], filter_name[-1], filter_input_value])
275
+ filter_div = components.update_filter_div(self.filter_list)
276
+ if len(self.filter_list) > 11:
277
+ filter_dropdown_div = filter_dropdown_disabled
278
+ filter_input_div = filter_input_disabled
279
+ _add_filter_save_btn_style = add_filter_save_btn_style_disabled
280
+ else:
281
+ filter_dropdown_div = filter_dropdown
282
+ filter_input_div = filter_input
283
+ self.init_chart = False
284
+ self.init_filter = False
280
285
 
281
286
  else:
282
287
  self.add_filter_btn_count = 0 # Necessary for initialization
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotguy
3
- Version: 2.2.4
3
+ Version: 2.3.1
4
4
  Summary: Plotguy
5
5
  Home-page: https://pypi.org/project/plotguy/
6
6
  Author: Plotguy Team
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="plotguy",
8
- version="2.2.4",
8
+ version="2.3.1",
9
9
  author="Plotguy Team",
10
10
  author_email="plotguy.info@gmail.com",
11
11
  description="Plotguy",
File without changes
File without changes
File without changes