seolpyo-mplchart 0.1.0__py3-none-any.whl → 0.1.3__py3-none-any.whl
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.
Potentially problematic release.
This version of seolpyo-mplchart might be problematic. Click here for more details.
- seolpyo_mplchart/__init__.py +2 -2
- seolpyo_mplchart/cursor.py +48 -39
- seolpyo_mplchart/draw.py +21 -23
- seolpyo_mplchart/slider.py +29 -33
- {seolpyo_mplchart-0.1.0.dist-info → seolpyo_mplchart-0.1.3.dist-info}/METADATA +7 -5
- seolpyo_mplchart-0.1.3.dist-info/RECORD +13 -0
- {seolpyo_mplchart-0.1.0.dist-info → seolpyo_mplchart-0.1.3.dist-info}/WHEEL +1 -1
- seolpyo_mplchart-0.1.0.dist-info/RECORD +0 -13
- {seolpyo_mplchart-0.1.0.dist-info → seolpyo_mplchart-0.1.3.dist-info}/top_level.txt +0 -0
seolpyo_mplchart/__init__.py
CHANGED
|
@@ -70,8 +70,8 @@ class Chart(CM):
|
|
|
70
70
|
textboxKwargs: Options that apply to the information text box. dufault dict(boxstyle='round', facecolor='w')
|
|
71
71
|
|
|
72
72
|
fraction: Decide whether to express information as a fraction. default False
|
|
73
|
-
candleformat: Candle information text format. default '{}\n\n종가: {}\n등락률: {}\n대비: {}\n시가: {}({})\n고가: {}({})\n저가: {}({})\n거래량: {}({})'
|
|
74
|
-
volumeformat: Volume information text format. default '{}\n\n거래량 : {}\n거래량증가율: {}'
|
|
73
|
+
candleformat: Candle information text format. default '{dt}\n\n종가: {close}\n등락률: {rate}\n대비: {compare}\n시가: {open}({rate_open})\n고가: {high}({rate_high})\n저가: {low}({rate_low})\n거래량: {volume}({rate_volume})'
|
|
74
|
+
volumeformat: Volume information text format. default '{dt}\n\n거래량 : {volume}\n거래량증가율: {rate_volume}'
|
|
75
75
|
digit_price, digit_volume: Number of decimal places expressed in informational text. default (0, 0)
|
|
76
76
|
|
|
77
77
|
min_distance: Minimum number of candles that can be selected with the slider. default 30
|
seolpyo_mplchart/cursor.py
CHANGED
|
@@ -14,6 +14,9 @@ class Mixin:
|
|
|
14
14
|
def on_draw(self, e):
|
|
15
15
|
"This function works if draw event active."
|
|
16
16
|
return
|
|
17
|
+
def on_move(self, e):
|
|
18
|
+
"This function works if mouse move event active."
|
|
19
|
+
return
|
|
17
20
|
|
|
18
21
|
|
|
19
22
|
class CollectionMixin(DrawMixin):
|
|
@@ -61,20 +64,27 @@ class CollectionMixin(DrawMixin):
|
|
|
61
64
|
_set_key = {'rate', 'compare', 'rate_open', 'rate_high', 'rate_low', 'rate_volume',}
|
|
62
65
|
|
|
63
66
|
class DataMixin(CollectionMixin):
|
|
64
|
-
def _generate_data(self, df, sort_df=True, calc_ma=True):
|
|
65
|
-
for i in
|
|
67
|
+
def _generate_data(self, df, sort_df=True, calc_ma=True, calc_info=True):
|
|
68
|
+
for i in ('date', 'Open', 'high', 'low', 'close', 'volume'):
|
|
66
69
|
v = getattr(self, i)
|
|
67
|
-
if v in _set_key:
|
|
70
|
+
if v in _set_key:
|
|
71
|
+
raise Exception(f'you can not set "self.{i}" value in {_set_key}.\nself.{i}={v!r}')
|
|
68
72
|
|
|
69
73
|
super()._generate_data(df, sort_df, calc_ma)
|
|
70
74
|
df = self.df
|
|
71
75
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
if not calc_info:
|
|
77
|
+
keys = set(df.keys())
|
|
78
|
+
for i in ('rate', 'compare', 'rate_open', 'rate_high', 'rate_low', 'rate_volume'):
|
|
79
|
+
if i not in keys:
|
|
80
|
+
raise Exception(f'"{i}" column not in DataFrame.\nadd column or set calc_info=True.')
|
|
81
|
+
else:
|
|
82
|
+
df['rate'] = ((df[self.close] - df[self.close].shift(1)) / df[self.close] * 100).__round__(2).fillna(0)
|
|
83
|
+
df['compare'] = (df[self.close] - df[self.close].shift(1)).fillna(0)
|
|
84
|
+
df['rate_open'] = ((df[self.Open] - df[self.close].shift(1)) / df[self.close] * 100).__round__(2).fillna(0)
|
|
85
|
+
df['rate_high'] = ((df[self.high] - df[self.close].shift(1)) / df[self.close] * 100).__round__(2).fillna(0)
|
|
86
|
+
df['rate_low'] = ((df[self.low] - df[self.close].shift(1)) / df[self.close] * 100).__round__(2).fillna(0)
|
|
87
|
+
df['rate_volume'] = ((df[self.volume] - df[self.volume].shift(1)) / df[self.volume].shift(1) * 100).__round__(2).fillna(0)
|
|
78
88
|
|
|
79
89
|
self.df = df
|
|
80
90
|
return
|
|
@@ -123,8 +133,10 @@ class LineMixin(DataMixin):
|
|
|
123
133
|
self.canvas.blit()
|
|
124
134
|
return
|
|
125
135
|
|
|
126
|
-
def
|
|
127
|
-
super().
|
|
136
|
+
def set_data(self, df, sort_df=True, calc_ma=True, change_lim=True, calc_info=True, *args, **kwargs):
|
|
137
|
+
return super().set_data(df, sort_df, calc_ma, change_lim, calc_info=calc_info, *args, **kwargs)
|
|
138
|
+
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True, calc_info=True, *args, **kwargs):
|
|
139
|
+
super()._set_data(df, sort_df, calc_ma, change_lim, calc_info=calc_info, *args, **kwargs)
|
|
128
140
|
|
|
129
141
|
self.vmin, self.vmax = (self.xmin, self.xmax)
|
|
130
142
|
return
|
|
@@ -242,12 +254,12 @@ class LineMixin(DataMixin):
|
|
|
242
254
|
|
|
243
255
|
class InfoMixin(LineMixin):
|
|
244
256
|
fraction = False
|
|
245
|
-
candleformat = '{}\n\n종가: {}\n등락률: {}\n대비: {}\n시가: {}({})\n고가: {}({})\n저가: {}({})\n거래량: {}({})'
|
|
246
|
-
volumeformat = '{}\n\n거래량 : {}\n거래량증가율: {}'
|
|
257
|
+
candleformat = '{dt}\n\n종가: {close}\n등락률: {rate}\n대비: {compare}\n시가: {open}({rate_open})\n고가: {high}({rate_high})\n저가: {low}({rate_low})\n거래량: {volume}({rate_volume})'
|
|
258
|
+
volumeformat = '{dt}\n\n거래량 : {volume}\n거래량증가율: {rate_volume}'
|
|
247
259
|
digit_price, digit_volume = (0, 0)
|
|
248
260
|
|
|
249
|
-
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True):
|
|
250
|
-
super()._set_data(df, sort_df, calc_ma, change_lim)
|
|
261
|
+
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True, calc_info=True, *args, **kwargs):
|
|
262
|
+
super()._set_data(df, sort_df, calc_ma, change_lim, calc_info, *args, **kwargs)
|
|
251
263
|
|
|
252
264
|
# 슬라이더 날짜 텍스트 y 위치
|
|
253
265
|
y = self._slider_ymax - (self._slider_ymax - self._slider_ymin) / 6
|
|
@@ -357,35 +369,35 @@ class InfoMixin(LineMixin):
|
|
|
357
369
|
else: l = float_to_str(ld[0])
|
|
358
370
|
|
|
359
371
|
text = self.candleformat.format(
|
|
360
|
-
dt,
|
|
361
|
-
f'{c:>{self._length_text}}{self.unit_price}',
|
|
362
|
-
f'{r:>{self._length_text}}%',
|
|
363
|
-
f'{com:>{self._length_text}}{self.unit_price}',
|
|
364
|
-
f'{o:>{self._length_text}}{self.unit_price}', f'{Or:+06,.2f}%',
|
|
365
|
-
f'{h:>{self._length_text}}{self.unit_price}', f'{hr:+06,.2f}%',
|
|
366
|
-
f'{l:>{self._length_text}}{self.unit_price}', f'{lr:+06,.2f}%',
|
|
367
|
-
f'{v:>{self._length_text}}{self.unit_volume}', f'{vr:+06,.2f}%',
|
|
372
|
+
dt=dt,
|
|
373
|
+
close=f'{c:>{self._length_text}}{self.unit_price}',
|
|
374
|
+
rate=f'{r:>{self._length_text}}%',
|
|
375
|
+
compare=f'{com:>{self._length_text}}{self.unit_price}',
|
|
376
|
+
open=f'{o:>{self._length_text}}{self.unit_price}', rate_open=f'{Or:+06,.2f}%',
|
|
377
|
+
high=f'{h:>{self._length_text}}{self.unit_price}', rate_high=f'{hr:+06,.2f}%',
|
|
378
|
+
low=f'{l:>{self._length_text}}{self.unit_price}', rate_low=f'{lr:+06,.2f}%',
|
|
379
|
+
volume=f'{v:>{self._length_text}}{self.unit_volume}', rate_volume=f'{vr:+06,.2f}%',
|
|
368
380
|
)
|
|
369
381
|
else:
|
|
370
382
|
o, h, l, c = (float_to_str(o, self.digit_price), float_to_str(h, self.digit_price), float_to_str(l, self.digit_price), float_to_str(c, self.digit_price))
|
|
371
383
|
com = float_to_str(compare, self.digit_price, plus=True)
|
|
372
384
|
|
|
373
385
|
text = self.candleformat.format(
|
|
374
|
-
dt,
|
|
375
|
-
f'{c:>{self._length_text}}{self.unit_price}',
|
|
376
|
-
f'{r:>{self._length_text}}%',
|
|
377
|
-
f'{com:>{self._length_text}}{self.unit_price}',
|
|
378
|
-
f'{o:>{self._length_text}}{self.unit_price}', f'{Or:+06,.2f}%',
|
|
379
|
-
f'{h:>{self._length_text}}{self.unit_price}', f'{hr:+06,.2f}%',
|
|
380
|
-
f'{l:>{self._length_text}}{self.unit_price}', f'{lr:+06,.2f}%',
|
|
381
|
-
f'{v:>{self._length_text}}{self.unit_volume}', f'{vr:+06,.2f}%',
|
|
386
|
+
dt=dt,
|
|
387
|
+
close=f'{c:>{self._length_text}}{self.unit_price}',
|
|
388
|
+
rate=f'{r:>{self._length_text}}%',
|
|
389
|
+
compare=f'{com:>{self._length_text}}{self.unit_price}',
|
|
390
|
+
open=f'{o:>{self._length_text}}{self.unit_price}', rate_open=f'{Or:+06,.2f}%',
|
|
391
|
+
high=f'{h:>{self._length_text}}{self.unit_price}', rate_high=f'{hr:+06,.2f}%',
|
|
392
|
+
low=f'{l:>{self._length_text}}{self.unit_price}', rate_low=f'{lr:+06,.2f}%',
|
|
393
|
+
volume=f'{v:>{self._length_text}}{self.unit_volume}', rate_volume=f'{vr:+06,.2f}%',
|
|
382
394
|
)
|
|
383
395
|
else:
|
|
384
396
|
vrate = f'{vr:+06,.2f}'
|
|
385
397
|
text = self.volumeformat.format(
|
|
386
|
-
dt,
|
|
387
|
-
f'{v:>{self._length_text}}{self.unit_volume}',
|
|
388
|
-
f'{vrate:>{self._length_text}}%',
|
|
398
|
+
dt=dt,
|
|
399
|
+
volume=f'{v:>{self._length_text}}{self.unit_volume}',
|
|
400
|
+
rate_volume=f'{vrate:>{self._length_text}}%',
|
|
389
401
|
)
|
|
390
402
|
return text
|
|
391
403
|
|
|
@@ -403,10 +415,6 @@ class Chart(CursorMixin, CM, Mixin):
|
|
|
403
415
|
self.on_pick(e)
|
|
404
416
|
return super()._on_pick(e)
|
|
405
417
|
|
|
406
|
-
def _blit(self):
|
|
407
|
-
super()._blit()
|
|
408
|
-
return self.on_blit()
|
|
409
|
-
|
|
410
418
|
def _on_move(self, e):
|
|
411
419
|
super()._on_move(e)
|
|
412
420
|
return self.on_move(e)
|
|
@@ -426,12 +434,13 @@ if __name__ == '__main__':
|
|
|
426
434
|
n = 2600
|
|
427
435
|
data = data[n:n+100]
|
|
428
436
|
df = pd.DataFrame(data)
|
|
437
|
+
print(f'{df.keys()=}')
|
|
429
438
|
|
|
430
439
|
t = time()
|
|
431
440
|
c = CursorMixin()
|
|
432
441
|
c.unit_price = '$'
|
|
433
442
|
# c.fraction = True
|
|
434
|
-
c.set_data(df
|
|
443
|
+
c.set_data(df[['date', 'open', 'high', 'low', 'close', 'volume']])
|
|
435
444
|
t2 = time() - t
|
|
436
445
|
print(f'{t2=}')
|
|
437
446
|
plt.show()
|
seolpyo_mplchart/draw.py
CHANGED
|
@@ -9,15 +9,9 @@ from .base import Base
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class Mixin:
|
|
12
|
-
def on_blit(self):
|
|
13
|
-
"This function works after cavas.blit()."
|
|
14
|
-
return
|
|
15
12
|
def on_draw(self, e):
|
|
16
13
|
"This function works if draw event active."
|
|
17
14
|
return
|
|
18
|
-
def on_move(self, e):
|
|
19
|
-
"This function works if mouse move event active."
|
|
20
|
-
return
|
|
21
15
|
def on_pick(self, e):
|
|
22
16
|
"This function works if pick event active."
|
|
23
17
|
return
|
|
@@ -37,20 +31,21 @@ class DataMixin(Base):
|
|
|
37
31
|
# https://matplotlib.org/stable/gallery/color/named_colors.html
|
|
38
32
|
list_macolor = ('darkred', 'fuchsia', 'olive', 'orange', 'navy', 'darkmagenta', 'limegreen', 'darkcyan',)
|
|
39
33
|
|
|
40
|
-
color_up = '#fe3032'
|
|
41
|
-
color_down = '#0095ff'
|
|
34
|
+
color_up, color_down = ('#fe3032', '#0095ff')
|
|
42
35
|
color_flat = 'k'
|
|
43
|
-
color_up_down = 'w'
|
|
44
|
-
color_down_up = 'w'
|
|
36
|
+
color_up_down, color_down_up = ('w', 'w')
|
|
45
37
|
colors_volume = '#1f77b4'
|
|
46
38
|
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
candlewidth_half, volumewidth_half = (0.3, 0.36)
|
|
40
|
+
|
|
41
|
+
def _generate_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, **_):
|
|
42
|
+
for i in ('date', 'Open', 'high', 'low', 'close', 'volume'):
|
|
49
43
|
k: str = getattr(self, i)
|
|
50
44
|
if k in _set_key: raise Exception(f'you can not set "self.{i}" value in {_set_key}.\nself.{i}={k!r}')
|
|
51
45
|
if i != 'date':
|
|
52
46
|
dtype = df[k].dtype
|
|
53
|
-
if not isinstance(dtype, (np.dtypes.Float64DType, np.dtypes.Int64DType, np.dtypes.Float32DType, np.dtypes.Int32DType)):
|
|
47
|
+
if not isinstance(dtype, (np.dtypes.Float64DType, np.dtypes.Int64DType, np.dtypes.Float32DType, np.dtypes.Int32DType)):
|
|
48
|
+
raise TypeError(f'column dtype must be one of "float64" or "int64" or "float32" or "int32".(excluding "date" column)\ndf[{k!r}].dtype={dtype!r}')
|
|
54
49
|
|
|
55
50
|
# DataFrame 정렬
|
|
56
51
|
if sort_df:
|
|
@@ -59,14 +54,17 @@ class DataMixin(Base):
|
|
|
59
54
|
if not self.list_ma: self.list_ma = tuple()
|
|
60
55
|
if calc_ma:
|
|
61
56
|
for i in self.list_ma: df[f'ma{i}'] = df[self.close].rolling(i).mean()
|
|
57
|
+
else:
|
|
58
|
+
keys = set(df.keys())
|
|
59
|
+
for i in self.list_ma:
|
|
60
|
+
if f'ma{i}' not in keys:
|
|
61
|
+
raise Exception(f'"ma{i}" column not in DataFrame.\nadd column or set calc_ma=True.')
|
|
62
62
|
|
|
63
|
-
candlewidth_half = 0.3
|
|
64
|
-
volumewidth_half = 0.36
|
|
65
63
|
df['x'] = df.index + 0.5
|
|
66
|
-
df['left'] = df['x'] - candlewidth_half
|
|
67
|
-
df['right'] = df['x'] + candlewidth_half
|
|
68
|
-
df['vleft'] = df['x'] - volumewidth_half
|
|
69
|
-
df['vright'] = df['x'] + volumewidth_half
|
|
64
|
+
df['left'] = df['x'] - self.candlewidth_half
|
|
65
|
+
df['right'] = df['x'] + self.candlewidth_half
|
|
66
|
+
df['vleft'] = df['x'] - self.volumewidth_half
|
|
67
|
+
df['vright'] = df['x'] + self.volumewidth_half
|
|
70
68
|
|
|
71
69
|
df['top'] = np.where(df[self.Open] <= df[self.close], df[self.close], df[self.Open])
|
|
72
70
|
df['top'] = np.where(df[self.close] < df[self.Open], df[self.Open], df[self.close])
|
|
@@ -303,12 +301,12 @@ class BackgroundMixin(CollectionMixin):
|
|
|
303
301
|
return
|
|
304
302
|
|
|
305
303
|
class DrawMixin(BackgroundMixin):
|
|
306
|
-
def set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True):
|
|
307
|
-
self._set_data(df, sort_df, calc_ma, change_lim)
|
|
304
|
+
def set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True, *_, **kwargs):
|
|
305
|
+
self._set_data(df, sort_df, calc_ma, change_lim, **kwargs)
|
|
308
306
|
return self.df
|
|
309
307
|
|
|
310
|
-
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True):
|
|
311
|
-
self._generate_data(df, sort_df, calc_ma)
|
|
308
|
+
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True, *_, **kwargs):
|
|
309
|
+
self._generate_data(df, sort_df, calc_ma, **kwargs)
|
|
312
310
|
self._set_collection()
|
|
313
311
|
self._draw_collection(change_lim)
|
|
314
312
|
return
|
seolpyo_mplchart/slider.py
CHANGED
|
@@ -6,15 +6,7 @@ import pandas as pd
|
|
|
6
6
|
from .cursor import CursorMixin, Chart as CM
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
v = x.values
|
|
11
|
-
return ((v[0], v[1]), (v[0], v[2]))
|
|
12
|
-
def get_volumeline(x: pd.Series):
|
|
13
|
-
v = x.values
|
|
14
|
-
return ((v[0], 0), (v[0], v[1]))
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class Mixin(CursorMixin):
|
|
9
|
+
class Mixin:
|
|
18
10
|
def on_click(self, e):
|
|
19
11
|
"This function works if mouse button click event active."
|
|
20
12
|
return
|
|
@@ -26,7 +18,7 @@ class Mixin(CursorMixin):
|
|
|
26
18
|
return
|
|
27
19
|
|
|
28
20
|
|
|
29
|
-
class NavgatorMixin(
|
|
21
|
+
class NavgatorMixin(CursorMixin):
|
|
30
22
|
min_distance = 30
|
|
31
23
|
color_navigatorline = '#1e78ff'
|
|
32
24
|
color_navigator = 'k'
|
|
@@ -43,8 +35,8 @@ class NavgatorMixin(Mixin):
|
|
|
43
35
|
self.ax_slider.add_artist(self.navigator)
|
|
44
36
|
return
|
|
45
37
|
|
|
46
|
-
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True):
|
|
47
|
-
super()._set_data(df, sort_df, calc_ma,
|
|
38
|
+
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True, calc_info=True):
|
|
39
|
+
super()._set_data(df, sort_df, calc_ma, change_lim, calc_info)
|
|
48
40
|
|
|
49
41
|
# 네비게이터 라인 선택 영역
|
|
50
42
|
xsub = self.xmax - self.xmin
|
|
@@ -156,8 +148,8 @@ class BackgroundMixin(NavgatorMixin):
|
|
|
156
148
|
|
|
157
149
|
|
|
158
150
|
class DrawMixin(BackgroundMixin):
|
|
159
|
-
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True):
|
|
160
|
-
super()._set_data(df, sort_df, calc_ma, change_lim)
|
|
151
|
+
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True, calc_info=True):
|
|
152
|
+
super()._set_data(df, sort_df, calc_ma, change_lim, calc_info)
|
|
161
153
|
|
|
162
154
|
# 네비게이터 높이 설정
|
|
163
155
|
ysub = self._slider_ymax - self._slider_ymin
|
|
@@ -319,6 +311,7 @@ class SimpleMixin(LimMixin):
|
|
|
319
311
|
simpler = False
|
|
320
312
|
limit_volume = 1_500
|
|
321
313
|
default_left, default_right = (180, 10)
|
|
314
|
+
_draw_blit = False
|
|
322
315
|
|
|
323
316
|
def __init__(self, *args, **kwargs):
|
|
324
317
|
super().__init__(*args, **kwargs)
|
|
@@ -334,8 +327,8 @@ class SimpleMixin(LimMixin):
|
|
|
334
327
|
self.ax_volume.add_collection(self.blitvolume)
|
|
335
328
|
return
|
|
336
329
|
|
|
337
|
-
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True):
|
|
338
|
-
super()._set_data(df, sort_df, calc_ma, False)
|
|
330
|
+
def _set_data(self, df: pd.DataFrame, sort_df=True, calc_ma=True, change_lim=True, calc_info=True):
|
|
331
|
+
super()._set_data(df, sort_df, calc_ma, False, calc_info)
|
|
339
332
|
|
|
340
333
|
seg = self.df[['x', self.high, 'x', self.low]].values
|
|
341
334
|
seg = seg.reshape(seg.shape[0], 2, 2)
|
|
@@ -369,19 +362,15 @@ class SimpleMixin(LimMixin):
|
|
|
369
362
|
self.ax_price.xaxis.draw(renderer)
|
|
370
363
|
self.ax_price.yaxis.draw(renderer)
|
|
371
364
|
|
|
372
|
-
left, right = self._navcoordinate
|
|
373
|
-
Range = right - left
|
|
374
365
|
if self.simpler:
|
|
375
|
-
if
|
|
376
|
-
else: self.
|
|
366
|
+
if self._draw_blit: self.priceline.draw(renderer)
|
|
367
|
+
else: self.blitcandle.draw(renderer)
|
|
377
368
|
elif self.candle_on_ma:
|
|
378
369
|
self.macollection.draw(renderer)
|
|
379
|
-
if
|
|
380
|
-
elif 800 < Range or 9_999 < self.xmax: self.blitcandle.draw(renderer)
|
|
370
|
+
if self._draw_blit: self.blitcandle.draw(renderer)
|
|
381
371
|
else: self.candlecollection.draw(renderer)
|
|
382
372
|
else:
|
|
383
|
-
if
|
|
384
|
-
elif 800 < Range or 9_999 < self.xmax: self.blitcandle.draw(renderer)
|
|
373
|
+
if self._draw_blit: self.blitcandle.draw(renderer)
|
|
385
374
|
else: self.candlecollection.draw(renderer)
|
|
386
375
|
self.macollection.draw(renderer)
|
|
387
376
|
|
|
@@ -477,9 +466,13 @@ class ClickMixin(SimpleMixin):
|
|
|
477
466
|
self._change_coordinate()
|
|
478
467
|
if self.is_click:
|
|
479
468
|
nsub = self._navcoordinate[1] - self._navcoordinate[0]
|
|
480
|
-
if self.min_distance <= nsub: self._lim()
|
|
481
469
|
if self.is_move: self._set_navigator(*self._navcoordinate)
|
|
482
|
-
|
|
470
|
+
else:
|
|
471
|
+
self._draw_blit = 900 < nsub
|
|
472
|
+
if self.intx is not None: self._set_navigator(self._x_click, self.intx)
|
|
473
|
+
|
|
474
|
+
if self.min_distance <= nsub: self._lim()
|
|
475
|
+
|
|
483
476
|
self.navigator.draw(self.canvas.renderer)
|
|
484
477
|
self._draw_blit_artist()
|
|
485
478
|
self._slider_move_action(e)
|
|
@@ -514,6 +507,10 @@ class Chart(SliderMixin, CM, Mixin):
|
|
|
514
507
|
self.on_pick(e)
|
|
515
508
|
return super()._on_pick(e)
|
|
516
509
|
|
|
510
|
+
def _on_move(self, e):
|
|
511
|
+
super()._on_move(e)
|
|
512
|
+
return self.on_move(e)
|
|
513
|
+
|
|
517
514
|
def _draw_artist(self):
|
|
518
515
|
super()._draw_artist()
|
|
519
516
|
return self.draw_artist()
|
|
@@ -521,13 +518,12 @@ class Chart(SliderMixin, CM, Mixin):
|
|
|
521
518
|
super()._draw_blit_artist()
|
|
522
519
|
return self.draw_artist()
|
|
523
520
|
|
|
524
|
-
def
|
|
525
|
-
super().
|
|
526
|
-
return self.
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
return self.on_move(e)
|
|
521
|
+
def _on_click(self, e):
|
|
522
|
+
super()._on_click(e)
|
|
523
|
+
return self.on_click(e)
|
|
524
|
+
def _on_release(self, e):
|
|
525
|
+
super()._on_release(e)
|
|
526
|
+
return self.on_release(e)
|
|
531
527
|
|
|
532
528
|
|
|
533
529
|
if __name__ == '__main__':
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: seolpyo-mplchart
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Fast candlestick chart using Python. Includes navigator, slider, navigation, and text information display functions
|
|
5
5
|
Author-email: white-seolpyo <white-seolpyo@naver.com>
|
|
6
6
|
License: MIT License
|
|
@@ -22,7 +22,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
23
|
Requires-Python: >=3.11
|
|
24
24
|
Description-Content-Type: text/markdown
|
|
25
|
-
Requires-Dist: matplotlib>=3.
|
|
25
|
+
Requires-Dist: matplotlib>=3.7.0
|
|
26
26
|
Requires-Dist: pandas>=2.0.0
|
|
27
27
|
|
|
28
28
|
# Donation
|
|
@@ -38,10 +38,12 @@ Ethereum: 0x1c5fb8a5e0b1153cd4116c91736bd16fabf83520
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
# Sample
|
|
41
|
-
|
|
41
|
+
<img alt="sample gif" src="https://github.com/white-seolpyo/seolpyo-mplchart/blob/main/images/sample.gif?raw=true">
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
<img alt="tkinter sample gif" src="https://github.com/white-seolpyo/seolpyo-mplchart/blob/main/images/with%20tkinter.gif?raw=true">
|
|
44
44
|
|
|
45
45
|

|
|
46
46
|
|
|
47
47
|

|
|
48
|
+
|
|
49
|
+
<img alt="40,000 sample" src="https://github.com/white-seolpyo/seolpyo-mplchart/blob/main/images/40000.gif?raw=true">
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
seolpyo_mplchart/__init__.py,sha256=FiuciCaX9lU12gwuDBYUNw0yLD06p4o7o19kR5jGips,5248
|
|
2
|
+
seolpyo_mplchart/base.py,sha256=vQ4OOBm3nGwjJ4wjDLaD_3LGxYzlP6AWpI6SZrZiwnQ,3600
|
|
3
|
+
seolpyo_mplchart/cursor.py,sha256=KSyYXJ1qVFgvrFBEhO8cazcZCxoJWqBAw0WvyVs9gNk,18405
|
|
4
|
+
seolpyo_mplchart/draw.py,sha256=NJH1dnmfepafMlc7K2ccwZbv0FDS3ItSiirCq4gMlOI,13145
|
|
5
|
+
seolpyo_mplchart/slider.py,sha256=R29vyNAdJkLEXgpP4hxe9O0WoLgoOnPOUHuKFNpdcnw,19601
|
|
6
|
+
seolpyo_mplchart/test.py,sha256=cW2hoaVbRtoSXlpmA4i1BKHBjI3-FAqYq__kryxkrC8,1007
|
|
7
|
+
seolpyo_mplchart/utils.py,sha256=-8cq4-WwiqKQxtwu3NPxOVTDDvoWH28tu4OTWr4hPTg,1208
|
|
8
|
+
seolpyo_mplchart/data/apple.txt,sha256=0izAfweu1lLsC0IwVthdVlo9reG8KGbKGTSX5knI5Zc,1380864
|
|
9
|
+
seolpyo_mplchart/data/samsung.txt,sha256=UejaSkbzr4E5K3lkelCT0yJiWUPfmViBEaTyoXyphIs,2476424
|
|
10
|
+
seolpyo_mplchart-0.1.3.dist-info/METADATA,sha256=Srf62CYZXlFvCYw4xqVy6DFtcEmun_dV3FymQXdzQyo,2347
|
|
11
|
+
seolpyo_mplchart-0.1.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
12
|
+
seolpyo_mplchart-0.1.3.dist-info/top_level.txt,sha256=KgqFn7rKWize7OjMaTCHxKm9ie6vqnyb5c8fN7y_tSo,17
|
|
13
|
+
seolpyo_mplchart-0.1.3.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
seolpyo_mplchart/__init__.py,sha256=HITw-PVvJA4AHOO_gOAsbBxNvEbou-JLtivnKA_dn0A,5157
|
|
2
|
-
seolpyo_mplchart/base.py,sha256=vQ4OOBm3nGwjJ4wjDLaD_3LGxYzlP6AWpI6SZrZiwnQ,3600
|
|
3
|
-
seolpyo_mplchart/cursor.py,sha256=_Pzg8WvfOpZYzN5uNLO9LH2wrRB_gZTNGkqmzsjaaPc,17309
|
|
4
|
-
seolpyo_mplchart/draw.py,sha256=yl813StbNuWC0_3QfS9ECvc0Z5buaIudsqR_qW8d3f4,13021
|
|
5
|
-
seolpyo_mplchart/slider.py,sha256=K-vPj2dsSyXZDELrgn6Ry5VqORgUc65gS2SsTFm5TmE,19725
|
|
6
|
-
seolpyo_mplchart/test.py,sha256=cW2hoaVbRtoSXlpmA4i1BKHBjI3-FAqYq__kryxkrC8,1007
|
|
7
|
-
seolpyo_mplchart/utils.py,sha256=-8cq4-WwiqKQxtwu3NPxOVTDDvoWH28tu4OTWr4hPTg,1208
|
|
8
|
-
seolpyo_mplchart/data/apple.txt,sha256=0izAfweu1lLsC0IwVthdVlo9reG8KGbKGTSX5knI5Zc,1380864
|
|
9
|
-
seolpyo_mplchart/data/samsung.txt,sha256=UejaSkbzr4E5K3lkelCT0yJiWUPfmViBEaTyoXyphIs,2476424
|
|
10
|
-
seolpyo_mplchart-0.1.0.dist-info/METADATA,sha256=W3N4J-vLlzw7Cx_t1WiGBDx2g0eiXdf5VlPoe0RVLDw,2176
|
|
11
|
-
seolpyo_mplchart-0.1.0.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
|
|
12
|
-
seolpyo_mplchart-0.1.0.dist-info/top_level.txt,sha256=KgqFn7rKWize7OjMaTCHxKm9ie6vqnyb5c8fN7y_tSo,17
|
|
13
|
-
seolpyo_mplchart-0.1.0.dist-info/RECORD,,
|
|
File without changes
|