seolpyo-mplchart 1.3.1.1__py3-none-any.whl → 1.4.0__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/_draw.py CHANGED
@@ -10,16 +10,12 @@ from ._base import Base
10
10
 
11
11
 
12
12
  class Mixin:
13
- def add_artist(self):
14
- "This method work when ```__init__()``` run."
15
- return
16
-
17
13
  def draw_artist(self):
18
14
  "This method work before ```figure.canvas.blit()```."
19
15
  return
20
16
 
21
- def generate_data(self):
22
- "This method work before create segments."
17
+ def on_change_xlim(self, xmin, xmax, simpler=False, set_ma=True):
18
+ "This method work if xlim change."
23
19
  return
24
20
 
25
21
  def on_draw(self, e):
@@ -30,10 +26,6 @@ class Mixin:
30
26
  "If draw pick active, This method work."
31
27
  return
32
28
 
33
- def set_segment(self, xmin, xmax, simpler=False, set_ma=True):
34
- "This method work if xlim change."
35
- return
36
-
37
29
 
38
30
  class CollectionMixin(Base):
39
31
  facecolor_volume, edgecolor_volume = ('#1f77b4', 'k')
@@ -46,23 +38,23 @@ class CollectionMixin(Base):
46
38
  return
47
39
 
48
40
  def _add_collection(self):
49
- self.collection_ma = LineCollection([], animated=True, linewidths=1)
50
- self.ax_price.add_collection(self.collection_ma)
41
+ self.artist_watermark = Text(
42
+ x=0.5, y=0.5, text=self.watermark,
43
+ animated=True,
44
+ fontsize=20, color=self.color_tick_label, alpha=0.2,
45
+ horizontalalignment='center', verticalalignment='center',
46
+ transform=self.ax_price.transAxes
47
+ )
48
+ self.ax_price.add_artist(self.artist_watermark)
51
49
 
52
50
  self.collection_candle = LineCollection([], animated=True, linewidths=0.8)
53
51
  self.ax_price.add_collection(self.collection_candle)
54
52
 
53
+ self.collection_ma = LineCollection([], animated=True, linewidths=1)
54
+ self.ax_price.add_collection(self.collection_ma)
55
+
55
56
  self.collection_volume = LineCollection([], animated=True, linewidths=1)
56
57
  self.ax_volume.add_collection(self.collection_volume)
57
-
58
- x = (self.adjust['right']-self.adjust['left']) / 2
59
- self.text_watermark = Text(
60
- x=x, y=0.51, text=self.watermark,
61
- animated=True,
62
- fontsize=20, color=self.color_tick_label, alpha=0.2,
63
- horizontalalignment='center', verticalalignment='center',
64
- )
65
- self.figure.add_artist(self.text_watermark)
66
58
  return
67
59
 
68
60
  def change_background_color(self, color):
@@ -86,7 +78,7 @@ class CollectionMixin(Base):
86
78
  return
87
79
 
88
80
  def change_text_color(self, color):
89
- self.text_watermark.set_color(color)
81
+ self.artist_watermark.set_color(color)
90
82
  legends = self.ax_legend.get_legend()
91
83
  if legends:
92
84
  for i in legends.texts: i.set_color(color)
@@ -95,13 +87,64 @@ class CollectionMixin(Base):
95
87
  def change_line_color(self, color): return
96
88
 
97
89
 
90
+ class DrawMixin(CollectionMixin):
91
+ candle_on_ma = True
92
+
93
+ def __init__(self, *args, **kwargs):
94
+ super().__init__(*args, **kwargs)
95
+
96
+ self._connect_event()
97
+ return
98
+
99
+ def _connect_event(self):
100
+ self.figure.canvas.mpl_connect('draw_event', lambda x: self._on_draw(x))
101
+ return
102
+
103
+ def _on_draw(self, e):
104
+ self._draw_artist()
105
+ self.figure.canvas.blit()
106
+ return
107
+
108
+ def _draw_artist(self):
109
+ self._draw_ax_price()
110
+ self._draw_ax_volume()
111
+ return
112
+
113
+ def _draw_ax_price(self):
114
+ renderer = self.figure.canvas.renderer
115
+
116
+ self.ax_price.xaxis.draw(renderer)
117
+ self.ax_price.yaxis.draw(renderer)
118
+
119
+ if self.candle_on_ma:
120
+ self.collection_ma.draw(renderer)
121
+ self.collection_candle.draw(renderer)
122
+ else:
123
+ self.collection_candle.draw(renderer)
124
+ self.collection_ma.draw(renderer)
125
+
126
+ if self.watermark:
127
+ self.artist_watermark.set_text(self.watermark)
128
+ self.artist_watermark.draw(renderer)
129
+ return
130
+
131
+ def _draw_ax_volume(self):
132
+ renderer = self.figure.canvas.renderer
133
+
134
+ self.ax_volume.xaxis.draw(renderer)
135
+ self.ax_volume.yaxis.draw(renderer)
136
+
137
+ self.collection_volume.draw(renderer)
138
+ return
139
+
140
+
98
141
  _set_key = {
99
142
  'x', 'zero', 'close_pre', 'ymax_volume',
100
143
  'top_candle', 'bottom_candle', 'left_candle', 'right_candle',
101
144
  'left_volume', 'right_volume',
102
145
  }
103
146
 
104
- class DataMixin(CollectionMixin):
147
+ class DataMixin(DrawMixin):
105
148
  df: pd.DataFrame
106
149
 
107
150
  date = 'date'
@@ -114,8 +157,8 @@ class DataMixin(CollectionMixin):
114
157
  color_flat = 'k'
115
158
  color_up_down, color_down_up = ('w', 'w')
116
159
 
117
- color_volume_up, color_volume_down = ('#FF4D4D', '#5CA8F4')
118
- color_volume_flat = '#A9A9A9'
160
+ color_volume_up, color_volume_down = ('#FF5555', '#5CA8F4')
161
+ color_volume_flat = '#909090'
119
162
 
120
163
  set_candlecolor, set_volumecolor = (True, True)
121
164
 
@@ -168,7 +211,6 @@ class DataMixin(CollectionMixin):
168
211
  v = getattr(self, i)
169
212
  if v in _set_key: raise Exception(f'you can not set "{i}" to column key.\nself.{i}={v!r}')
170
213
 
171
-
172
214
  if not self.set_candlecolor:
173
215
  keys = set(df.keys())
174
216
  for i in ('facecolor', 'edgecolor', 'facecolor_volume', 'edgecolor_volume',):
@@ -180,23 +222,14 @@ class DataMixin(CollectionMixin):
180
222
  for i in ('facecolor_volume', 'edgecolor_volume',):
181
223
  if i not in keys:
182
224
  raise Exception(f'"{i}" column not in DataFrame.\nadd column or set set_volumecolor=True.')
183
-
184
225
  return
185
226
 
186
227
 
187
- class SegmentMixin(DataMixin):
188
- _visible_ma = set()
189
-
190
- limit_candle = 800
191
- limit_wick = 4_000
192
- limit_volume = 200
193
-
228
+ class CandleSegmentMixin(DataMixin):
194
229
  color_priceline = 'k'
195
- format_ma = '{}일선'
196
- # https://matplotlib.org/stable/gallery/color/named_colors.html
197
- list_macolor = ('#B22222', '#228B22', '#1E90FF', '#FF8C00', '#4B0082')
230
+ limit_candle = 800
198
231
 
199
- def _get_segments(self):
232
+ def _create_candle_segments(self):
200
233
  # 캔들 세그먼트
201
234
  segment_candle = self.df[[
202
235
  'x', self.high,
@@ -225,28 +258,10 @@ class SegmentMixin(DataMixin):
225
258
  segment_priceline = segment_wick = self.df[['x', self.close]].values
226
259
  self.segment_priceline = segment_priceline.reshape(1, *segment_wick.shape)
227
260
 
228
- if self.volume:
229
- # 거래량 바 세그먼트
230
- segment_volume = self.df[[
231
- 'left_volume', 'zero',
232
- 'left_volume', self.volume,
233
- 'right_volume', self.volume,
234
- 'right_volume', 'zero',
235
- ]].values
236
- self.segment_volume = segment_volume.reshape(segment_volume.shape[0], 4, 2)
237
-
238
- # 거래량 심지 세그먼트
239
- segment_volume_wick = self.df[[
240
- 'x', 'zero',
241
- 'x', self.volume,
242
- ]].values
243
- self.segment_volume_wick = segment_volume_wick.reshape(segment_volume_wick.shape[0], 2, 2)
244
-
245
- self._get_ma_segment()
246
- self._get_color_segment()
261
+ self._create_candle_color_segments()
247
262
  return
248
263
 
249
- def _get_color_segment(self):
264
+ def _create_candle_color_segments(self):
250
265
  if self.set_candlecolor:
251
266
  # 양봉
252
267
  self.df.loc[:, ['facecolor', 'edgecolor']] = (self.color_up, self.color_up)
@@ -265,20 +280,48 @@ class SegmentMixin(DataMixin):
265
280
 
266
281
  self.facecolor_candle = self.df['facecolor'].values
267
282
  self.edgecolor_candle = self.df['edgecolor'].values
283
+ return
268
284
 
269
- if self.set_volumecolor:
270
- # 거래량
271
- self.df.loc[:, ['facecolor_volume', 'edgecolor_volume']] = (self.color_volume_up, self.color_volume_up)
272
- if self.color_up != self.color_down:
273
- # 전일대비 하락
274
- self.df.loc[self.df[self.close] < self.df['close_pre'], ['facecolor_volume', 'edgecolor_volume']] = (self.color_volume_down, self.color_volume_down)
275
- if self.color_up != self.color_flat:
276
- # 전일과 동일
277
- self.df.loc[self.df[self.close] == self.df['close_pre'], ['facecolor_volume', 'edgecolor_volume']] = (self.color_volume_flat, self.color_volume_flat)
285
+ def _set_candle_segments(self, index_start, index_end):
286
+ self.collection_candle.set_segments(self.segment_candle[index_start:index_end])
287
+ self.collection_candle.set_facecolor(self.facecolor_candle[index_start:index_end])
288
+ self.collection_candle.set_edgecolor(self.edgecolor_candle[index_start:index_end])
289
+ return
278
290
 
279
- self.facecolor_volume = self.df['facecolor_volume'].values
280
- self.edgecolor_volume = self.df['edgecolor_volume'].values
291
+ def _set_candle_wick_segments(self, index_start, index_end):
292
+ self.collection_candle.set_segments(self.segment_candle_wick[index_start:index_end])
293
+ self.collection_candle.set_facecolor([])
294
+ self.collection_candle.set_edgecolor(self.edgecolor_candle[index_start:index_end])
295
+ return
296
+
297
+ def _set_priceline_segments(self, index_start, index_end):
298
+ self.collection_candle.set_segments(self.segment_priceline[:, index_start:index_end])
299
+ self.collection_candle.set_facecolor([])
300
+ self.collection_candle.set_edgecolor(self.color_priceline)
301
+ return
302
+
303
+
304
+ class MaSegmentMixin(CandleSegmentMixin):
305
+ format_ma = '{}일선'
306
+ # https://matplotlib.org/stable/gallery/color/named_colors.html
307
+ list_macolor = ('#006400', '#8B008B', '#FFA500', '#0000FF', '#FF0000')
308
+
309
+ _visible_ma = set()
310
+
311
+ def _create_ma_segments(self):
312
+ # 주가 차트 가격이동평균선
313
+ key_ma = []
314
+ for i in reversed(self.list_ma):
315
+ key_ma.append('x')
316
+ key_ma.append(f'ma{i}')
317
+ if key_ma:
318
+ segment_ma = self.df[key_ma].values
319
+ self.segment_ma = segment_ma.reshape(segment_ma.shape[0], len(self.list_ma), 2).swapaxes(0, 1)
281
320
 
321
+ self._create_ma_color_segments()
322
+ return
323
+
324
+ def _create_ma_color_segments(self):
282
325
  # 기존 legend 제거
283
326
  legends = self.ax_legend.get_legend()
284
327
  if legends: legends.remove()
@@ -286,7 +329,7 @@ class SegmentMixin(DataMixin):
286
329
  self._visible_ma.clear()
287
330
 
288
331
  list_handle, list_label, list_color = ([], [], [])
289
- arr = (0, 1)
332
+ arr = [0, 1]
290
333
  for n, i in enumerate(self.list_ma):
291
334
  try: c = self.list_macolor[n]
292
335
  except: c = self.color_priceline
@@ -308,106 +351,108 @@ class SegmentMixin(DataMixin):
308
351
  for i in legends.legend_handles: i.set_picker(5)
309
352
  return
310
353
 
311
- def _get_ma_segment(self):
312
- if not self.list_ma: return
313
-
314
- # 주가 차트 가격이동평균선
315
- key_ma = []
316
- for i in reversed(self.list_ma):
317
- key_ma.append('x')
318
- key_ma.append(f'ma{i}')
319
- segment_ma = self.df[key_ma].values
320
- self.segment_ma = segment_ma.reshape(segment_ma.shape[0], len(self.list_ma), 2).swapaxes(0, 1)
354
+ def _set_ma_segments(self, index_start, index_end, set_ma):
355
+ if not set_ma: self.collection_ma.set_segments([])
356
+ else:
357
+ self.collection_ma.set_segments(self.segment_ma[:, index_start:index_end])
358
+ self.collection_ma.set_edgecolor(self.edgecolor_ma)
321
359
  return
322
360
 
323
- def _set_segments(self, index_start, index_end, simpler, set_ma):
324
- indsub = index_end - index_start
325
- if index_start < 0: index_start = 0
326
- if index_end < 1: index_end = 1
327
361
 
328
- index_end += 2
329
- if indsub < self.limit_candle:
330
- self._set_candle_segments(index_start, index_end)
331
- elif indsub < self.limit_wick:
332
- self._set_wick_segments(index_start, index_end, simpler)
333
- else:
334
- self._set_line_segments(index_start, index_end, simpler, set_ma)
335
- return
362
+ class VolumeSegmentMixin(MaSegmentMixin):
363
+ limit_volume = 200
336
364
 
337
- def _set_candle_segments(self, index_start, index_end):
338
- self.collection_candle.set_segments(self.segment_candle[index_start:index_end])
339
- self.collection_candle.set_facecolor(self.facecolor_candle[index_start:index_end])
340
- self.collection_candle.set_edgecolor(self.edgecolor_candle[index_start:index_end])
365
+ def _create_volume_segments(self):
366
+ # 거래량 바 세그먼트
367
+ segment_volume = self.df[[
368
+ 'left_volume', 'zero',
369
+ 'left_volume', self.volume,
370
+ 'right_volume', self.volume,
371
+ 'right_volume', 'zero',
372
+ ]].values
373
+ self.segment_volume = segment_volume.reshape(segment_volume.shape[0], 4, 2)
341
374
 
342
- if self.volume:
343
- self.collection_volume.set_segments(self.segment_volume[index_start:index_end])
344
- self.collection_volume.set_linewidth(0.7)
345
- self.collection_volume.set_facecolor(self.facecolor_volume[index_start:index_end])
346
- self.collection_volume.set_edgecolor(self.edgecolor_volume[index_start:index_end])
375
+ # 거래량 심지 세그먼트
376
+ segment_volume_wick = self.df[[
377
+ 'x', 'zero',
378
+ 'x', self.volume,
379
+ ]].values
380
+ self.segment_volume_wick = segment_volume_wick.reshape(segment_volume_wick.shape[0], 2, 2)
347
381
 
348
- self.collection_ma.set_segments(self.segment_ma[:, index_start:index_end])
349
- self.collection_ma.set_edgecolor(self.edgecolor_ma)
382
+ self._create_volume_color_segments()
350
383
  return
351
384
 
352
- def _set_wick_segments(self, index_start, index_end, simpler=False):
353
- self.collection_candle.set_segments(self.segment_candle_wick[index_start:index_end])
354
- self.collection_candle.set_facecolor([])
355
- self.collection_candle.set_edgecolor(self.edgecolor_candle[index_start:index_end])
385
+ def _create_volume_color_segments(self):
386
+ if self.set_volumecolor:
387
+ columns = ['facecolor_volume', 'edgecolor_volume']
388
+ # 거래량
389
+ self.df.loc[:, columns] = (self.color_volume_up, self.color_volume_up)
390
+ if self.color_up != self.color_down:
391
+ # 전일대비 하락
392
+ condition = self.df[self.close] < self.df['close_pre']
393
+ self.df.loc[condition, columns] = (self.color_volume_down, self.color_volume_down)
394
+ if self.color_up != self.color_flat:
395
+ # 전일과 동일
396
+ condition = self.df[self.close] == self.df['close_pre']
397
+ self.df.loc[condition, columns] = (self.color_volume_flat, self.color_volume_flat)
356
398
 
357
- if self.volume:
358
- seg_volume = self.segment_volume_wick[index_start:index_end]
359
- seg_facecolor_volume = self.facecolor_volume[index_start:index_end]
360
- seg_edgecolor_volume = self.edgecolor_volume[index_start:index_end]
361
- if simpler:
362
- values = seg_volume[:, 1, 1]
363
- top_index = np.argsort(-values)[:self.limit_volume]
364
- seg_volume = seg_volume[top_index]
365
- seg_facecolor_volume = seg_facecolor_volume[top_index]
366
- seg_edgecolor_volume = seg_edgecolor_volume[top_index]
367
- self.collection_volume.set_segments(seg_volume)
368
- self.collection_volume.set_linewidth(1.3)
369
- self.collection_volume.set_facecolor(seg_facecolor_volume)
370
- self.collection_volume.set_edgecolor(seg_edgecolor_volume)
371
-
372
- self.collection_ma.set_segments(self.segment_ma[:, index_start:index_end])
373
- self.collection_ma.set_edgecolor(self.edgecolor_ma)
374
- return
375
-
376
- def _set_line_segments(self, index_start, index_end, simpler=False, set_ma=True):
377
- self.collection_candle.set_segments(self.segment_priceline[:, index_start:index_end])
378
- self.collection_candle.set_facecolor([])
379
- self.collection_candle.set_edgecolor(self.color_priceline)
399
+ self.facecolor_volume = self.df['facecolor_volume'].values
400
+ self.edgecolor_volume = self.df['edgecolor_volume'].values
401
+ return
380
402
 
381
- if self.volume:
382
- seg_volume = self.segment_volume_wick[index_start:index_end]
383
- seg_facecolor_volume = self.facecolor_volume[index_start:index_end]
384
- seg_edgecolor_volume = self.edgecolor_volume[index_start:index_end]
385
- if simpler:
386
- values = seg_volume[:, 1, 1]
387
- top_index = np.argsort(-values)[:self.limit_volume]
388
- seg_volume = seg_volume[top_index]
389
- seg_facecolor_volume = seg_facecolor_volume[top_index]
390
- seg_edgecolor_volume = seg_edgecolor_volume[top_index]
391
- self.collection_volume.set_segments(seg_volume)
392
- self.collection_volume.set_linewidth(1.3)
393
- self.collection_volume.set_facecolor(seg_facecolor_volume)
394
- self.collection_volume.set_edgecolor(seg_edgecolor_volume)
403
+ def _set_volume_segments(self, index_start, index_end):
404
+ self.collection_volume.set_segments(self.segment_volume[index_start:index_end])
405
+ self.collection_volume.set_linewidth(0.7)
406
+ self.collection_volume.set_facecolor(self.facecolor_volume[index_start:index_end])
407
+ self.collection_volume.set_edgecolor(self.edgecolor_volume[index_start:index_end])
408
+ return
395
409
 
396
- if not set_ma: self.collection_ma.set_segments([])
397
- else:
398
- self.collection_ma.set_segments(self.segment_ma[:, index_start:index_end])
399
- self.collection_ma.set_edgecolor(self.edgecolor_ma)
410
+ def _set_volume_wick_segments(self, index_start, index_end, simpler):
411
+ seg_volume = self.segment_volume_wick[index_start:index_end]
412
+ seg_facecolor_volume = self.facecolor_volume[index_start:index_end]
413
+ seg_edgecolor_volume = self.edgecolor_volume[index_start:index_end]
414
+ if simpler:
415
+ values = seg_volume[:, 1, 1]
416
+ top_index = np.argsort(-values)[:self.limit_volume]
417
+ seg_volume = seg_volume[top_index]
418
+ seg_facecolor_volume = seg_facecolor_volume[top_index]
419
+ seg_edgecolor_volume = seg_edgecolor_volume[top_index]
420
+ self.collection_volume.set_segments(seg_volume)
421
+ self.collection_volume.set_linewidth(1.3)
422
+ self.collection_volume.set_facecolor(seg_facecolor_volume)
423
+ self.collection_volume.set_edgecolor(seg_edgecolor_volume)
400
424
  return
401
425
 
402
426
 
403
- class EventMixin(SegmentMixin):
404
- def __init__(self, *args, **kwargs):
405
- super().__init__(*args, **kwargs)
427
+ class SegmentMixin(VolumeSegmentMixin):
428
+ limit_wick = 4_000
406
429
 
407
- self._connect_event()
430
+ def _create_segments(self):
431
+ self._create_candle_segments()
432
+ self._create_ma_segments()
433
+ if self.volume: self._create_volume_segments()
408
434
  return
409
435
 
436
+ def _set_collection_segments(self, index_start, index_end, indsub, simpler, set_ma=True):
437
+ if indsub < self.limit_candle:
438
+ self._set_candle_segments(index_start, index_end)
439
+ self._set_ma_segments(index_start, index_end, set_ma)
440
+ if self.volume: self._set_volume_segments(index_start, index_end)
441
+ elif indsub < self.limit_wick:
442
+ self._set_candle_wick_segments(index_start, index_end)
443
+ self._set_ma_segments(index_start, index_end, set_ma)
444
+ if self.volume: self._set_volume_wick_segments(index_start, index_end, simpler)
445
+ else:
446
+ self._set_priceline_segments(index_start, index_end)
447
+ self._set_ma_segments(index_start, index_end, set_ma)
448
+ if self.volume: self._set_volume_wick_segments(index_start, index_end, simpler)
449
+ return
450
+
451
+
452
+ class EventMixin(SegmentMixin):
410
453
  def _connect_event(self):
454
+ super()._connect_event()
455
+
411
456
  self.figure.canvas.mpl_connect('pick_event', lambda x: self._on_pick(x))
412
457
  return
413
458
 
@@ -417,12 +462,9 @@ class EventMixin(SegmentMixin):
417
462
 
418
463
  def _pick_ma_action(self, e: PickEvent):
419
464
  handle = e.artist
420
- if handle.get_alpha() == 0.2:
421
- visible = True
422
- handle.set_alpha(1.0)
423
- else:
424
- visible = False
425
- handle.set_alpha(0.2)
465
+
466
+ visible = handle.get_alpha() == 0.2
467
+ handle.set_alpha(1.0 if visible else 0.2)
426
468
 
427
469
  n = int(handle.get_label())
428
470
  if visible: self._visible_ma = {i for i in self.list_ma if i in self._visible_ma or i == n}
@@ -431,68 +473,25 @@ class EventMixin(SegmentMixin):
431
473
  alphas = [(1 if i in self._visible_ma else 0) for i in reversed(self.list_ma)]
432
474
  self.collection_ma.set_alpha(alphas)
433
475
 
434
- self._draw()
435
- return
436
-
437
- def _draw(self):
438
476
  self.figure.canvas.draw()
439
477
  return
440
478
 
441
479
 
442
- class DrawMixin(EventMixin):
480
+ class LimMixin(EventMixin):
443
481
  candle_on_ma = True
444
482
 
445
483
  def set_data(self, df, sort_df=True, calc_ma=True, set_candlecolor=True, set_volumecolor=True, *args, **kwargs):
446
484
  self._generate_data(df, sort_df, calc_ma, set_candlecolor, set_volumecolor, *args, **kwargs)
447
- self._get_segments()
485
+ self._create_segments()
448
486
 
449
487
  vmin, vmax = self.get_default_lim()
450
488
  self._set_lim(vmin, vmax)
451
489
  return
452
490
 
453
- def _connect_event(self):
454
- super()._connect_event()
455
- self.figure.canvas.mpl_connect('draw_event', lambda x: self._on_draw(x))
456
- return
457
-
458
- def _on_draw(self, e):
459
- self._draw_artist()
460
- self._blit()
461
- return
462
-
463
- def _draw_artist(self):
464
- renderer = self.figure.canvas.renderer
465
-
466
- self.ax_price.xaxis.draw(renderer)
467
- self.ax_price.yaxis.draw(renderer)
468
-
469
- if self.candle_on_ma:
470
- self.collection_ma.draw(renderer)
471
- self.collection_candle.draw(renderer)
472
- else:
473
- self.collection_candle.draw(renderer)
474
- self.collection_ma.draw(renderer)
475
-
476
- if self.watermark:
477
- self.text_watermark.set_text(self.watermark)
478
- self.text_watermark.draw(renderer)
479
-
480
- self.ax_volume.xaxis.draw(renderer)
481
- self.ax_volume.yaxis.draw(renderer)
482
-
483
- self.collection_volume.draw(renderer)
484
- return
485
-
486
- def _blit(self):
487
- self.figure.canvas.blit()
488
- return
489
-
490
491
  def _set_lim(self, xmin, xmax, simpler=False, set_ma=True):
491
- self.vxmin, self.vxmax = (xmin, xmax + 1)
492
+ self.vxmin, self.vxmax = (xmin, xmax)
492
493
  if xmin < 0: xmin = 0
493
- if xmax < 0: xmax = 0
494
- xmax += 1
495
- if xmin == xmax: xmax += 1
494
+ if xmax < 1: xmax = 1
496
495
 
497
496
  ymin, ymax = (self.df[self.low][xmin:xmax].min(), self.df[self.high][xmin:xmax].max())
498
497
  yspace = (ymax - ymin) / 15
@@ -502,8 +501,9 @@ class DrawMixin(EventMixin):
502
501
  # 거래량 차트 ymax
503
502
  self.volume_ymax = self.df['ymax_volume'][xmin:xmax].max() if self.volume else 1
504
503
 
505
- self._set_segments(xmin, xmax, simpler, set_ma)
506
504
  self._change_lim(self.vxmin, self.vxmax)
505
+ xsub = xmax - xmin
506
+ self._set_collection_segments(xmin, xmax, xsub, simpler, set_ma)
507
507
  return
508
508
 
509
509
  def _change_lim(self, xmin, xmax):
@@ -519,19 +519,14 @@ class DrawMixin(EventMixin):
519
519
  return
520
520
 
521
521
  def get_default_lim(self):
522
- return (0, self.list_index[-1])
522
+ return (0, self.list_index[-1]+1)
523
523
 
524
524
 
525
- class BackgroundMixin(DrawMixin):
525
+ class BackgroundMixin(LimMixin):
526
526
  background = None
527
527
 
528
528
  _creating_background = False
529
529
 
530
- def _connect_event(self):
531
- self.figure.canvas.mpl_connect('pick_event', lambda x: self._on_pick(x))
532
- self.figure.canvas.mpl_connect('draw_event', lambda x: self._on_draw(x))
533
- return
534
-
535
530
  def _create_background(self):
536
531
  if self._creating_background: return
537
532
 
@@ -562,17 +557,13 @@ class BaseMixin(BackgroundMixin):
562
557
 
563
558
 
564
559
  class Chart(BaseMixin, Mixin):
565
- def _add_collection(self):
566
- super()._add_collection()
567
- return self.add_artist()
568
-
569
560
  def _draw_artist(self):
570
561
  super()._draw_artist()
571
562
  return self.draw_artist()
572
563
 
573
- def _get_segments(self):
574
- self.generate_data()
575
- return super()._get_segments()
564
+ def _set_lim(self, xmin, xmax, simpler=False, set_ma=True):
565
+ super()._set_lim(xmin, xmax, simpler, set_ma)
566
+ return self.on_change_xlim(xmin, xmax, simpler, set_ma)
576
567
 
577
568
  def _on_draw(self, e):
578
569
  super()._on_draw(e)
@@ -582,18 +573,3 @@ class Chart(BaseMixin, Mixin):
582
573
  self.on_pick(e)
583
574
  return super()._on_pick(e)
584
575
 
585
- def _set_candle_segments(self, index_start, index_end):
586
- super()._set_candle_segments(index_start, index_end)
587
- self.set_segment(index_start, index_end)
588
- return
589
-
590
- def _set_wick_segments(self, index_start, index_end, simpler=False):
591
- super()._set_wick_segments(index_start, index_end, simpler)
592
- self.set_segment(index_start, index_end, simpler)
593
- return
594
-
595
- def _set_line_segments(self, index_start, index_end, simpler=False, set_ma=True):
596
- super()._set_line_segments(index_start, index_end, simpler, set_ma)
597
- self.set_segment(index_start, index_end, simpler, set_ma)
598
- return
599
-