Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1bf18a6

Browse files
Merge pull request #451 from AurumnPegasus/master
Set single candle color
2 parents d858138 + 28b05ca commit 1bf18a6

File tree

10 files changed

+1279
-34
lines changed

10 files changed

+1279
-34
lines changed

‎examples/marketcolor_overrides.ipynb

Lines changed: 831 additions & 0 deletions
Large diffs are not rendered by default.

‎examples/scratch_pad/pr451_test.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import pandas as pd
2+
import mplfinance as mpf
3+
import ast
4+
5+
df = pd.read_csv('pr451data.csv',index_col=0,parse_dates=True)
6+
7+
print(df.head(3))
8+
9+
custom_colors = []
10+
for i in range(len(df)):
11+
if i % 3 == 0:
12+
#custom_colors.append(mpf.make_marketcolors(up='#29c9ff', down='#f3b5ff', edge='#29c9ff', wick='#29c9ff', ohlc='#32a852', volume='#a89132'))
13+
custom_colors.append(mpf.make_marketcolors(up='#29c9ff',down='#f3b5ff',edge='#29c9ff',wick='#29c9ff',
14+
ohlc={'up':'lime','down':'blue'}, volume='#a89132'))
15+
elif i%5 == 0:
16+
custom_colors.append("#000000")
17+
else:
18+
custom_colors.append(None)
19+
20+
#STYLE = 'binance'
21+
STYLE = 'yahoo'
22+
23+
#mpf.plot(df, type='candle',style=STYLE,volume=True,block=False,figscale=1.25,savefig='pr451t2no.jpg')
24+
#mpf.plot(df, type='ohlc',style=STYLE,volume=True,block=False,figscale=1.25)
25+
mpf.plot(df, type='candle',style=STYLE,volume=True,block=False,figscale=1.25)
26+
#mpf.plot(df, type='hollow',style=STYLE,volume=True,block=False,figscale=1.25)
27+
28+
#mpf.plot(df, type='candle',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25,savefig='pr451t2ye.jpg')
29+
#mpf.plot(df, type='ohlc',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25)
30+
mpf.plot(df, type='candle',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25)
31+
#mpf.plot(df, type='hollow',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25)

‎examples/scratch_pad/pr451_testing.ipynb

Lines changed: 180 additions & 0 deletions
Large diffs are not rendered by default.

‎examples/scratch_pad/pr451data.csv

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
Date,Open,Close,High,Low,Date,Volume
2+
2019年09月01日,29,20,29,20,2019年09月01日,10787
3+
2019年09月02日,29,31,33,23,2019年09月02日,17215
4+
2019年09月03日,29,20,29,20,2019年09月03日,16697
5+
2019年09月04日,24,16,24,15,2019年09月04日,12104
6+
2019年09月05日,23,20,25,15,2019年09月05日,12159
7+
2019年09月06日,22,24,24,20,2019年09月06日,13618
8+
2019年09月07日,19,15,22,14,2019年09月07日,13645
9+
2019年09月08日,13,13,15,13,2019年09月08日,13472
10+
2019年09月09日,20,16,20,14,2019年09月09日,17861
11+
2019年09月10日,17,25,25,16,2019年09月10日,18565
12+
2019年09月11日,30,24,30,23,2019年09月11日,10283
13+
2019年09月12日,24,25,26,19,2019年09月12日,10102
14+
2019年09月13日,22,22,26,21,2019年09月13日,17100
15+
2019年09月14日,27,28,28,21,2019年09月14日,13079
16+
2019年09月15日,26,29,29,26,2019年09月15日,10800
17+
2019年09月16日,30,23,30,21,2019年09月16日,17927
18+
2019年09月17日,30,27,30,26,2019年09月17日,16355
19+
2019年09月18日,22,27,29,22,2019年09月18日,12066
20+
2019年09月19日,19,23,23,18,2019年09月19日,19733
21+
2019年09月20日,21,14,24,14,2019年09月20日,14761
22+
2019年09月21日,24,23,24,19,2019年09月21日,19410
23+
2019年09月22日,15,25,25,15,2019年09月22日,17238
24+
2019年09月23日,23,20,26,18,2019年09月23日,10840
25+
2019年09月24日,18,25,26,17,2019年09月24日,17668
26+
2019年09月25日,23,28,29,23,2019年09月25日,19267
27+
2019年09月26日,30,26,31,26,2019年09月26日,18340
28+
2019年09月27日,33,28,37,27,2019年09月27日,18905
29+
2019年09月28日,26,25,34,25,2019年09月28日,16682
30+
2019年09月29日,31,27,32,24,2019年09月29日,12605
31+
2019年09月30日,30,31,32,23,2019年09月30日,12702
32+
2019年10月01日,37,31,38,29,2019年10月01日,17485
33+
2019年10月02日,41,39,42,39,2019年10月02日,12198
34+
2019年10月03日,39,45,46,37,2019年10月03日,14923
35+
2019年10月04日,41,48,50,41,2019年10月04日,10326
36+
2019年10月05日,41,44,47,40,2019年10月05日,17738
37+
2019年10月06日,47,49,52,46,2019年10月06日,13330
38+
2019年10月07日,47,45,48,38,2019年10月07日,19102
39+
2019年10月08日,43,44,45,39,2019年10月08日,16682
40+
2019年10月09日,40,32,41,32,2019年10月09日,12813
41+
2019年10月10日,46,38,46,36,2019年10月10日,12306
42+
2019年10月11日,44,42,45,38,2019年10月11日,17205
43+
2019年10月12日,44,44,44,35,2019年10月12日,14736
44+
2019年10月13日,39,41,42,34,2019年10月13日,19296
45+
2019年10月14日,34,31,34,31,2019年10月14日,12587
46+
2019年10月15日,32,31,33,31,2019年10月15日,14709
47+
2019年10月16日,42,36,43,36,2019年10月16日,18555
48+
2019年10月17日,43,40,43,40,2019年10月17日,18850
49+
2019年10月18日,37,41,41,37,2019年10月18日,14650
50+
2019年10月19日,31,37,38,31,2019年10月19日,10405
51+
2019年10月20日,26,34,35,26,2019年10月20日,12074
52+
2019年10月21日,34,30,34,26,2019年10月21日,17407
53+
2019年10月22日,23,32,32,22,2019年10月22日,18649
54+
2019年10月23日,20,23,27,18,2019年10月23日,16161
55+
2019年10月24日,20,18,20,18,2019年10月24日,14008
56+
2019年10月25日,20,21,25,19,2019年10月25日,16251
57+
2019年10月26日,19,17,24,17,2019年10月26日,14594
58+
2019年10月27日,29,20,29,19,2019年10月27日,10994
59+
2019年10月28日,28,26,30,23,2019年10月28日,16978
60+
2019年10月29日,30,22,30,22,2019年10月29日,11373
61+
2019年10月30日,18,26,28,18,2019年10月30日,11589
62+
2019年10月31日,26,21,31,21,2019年10月31日,14787
63+
2019年11月01日,19,25,26,18,2019年11月01日,15088
64+
2019年11月02日,25,26,27,22,2019年11月02日,10827
65+
2019年11月03日,24,28,28,22,2019年11月03日,12281
66+
2019年11月04日,24,15,24,15,2019年11月04日,19768
67+
2019年11月05日,22,17,23,15,2019年11月05日,11398
68+
2019年11月06日,20,23,25,18,2019年11月06日,15819
69+
2019年11月07日,20,26,26,17,2019年11月07日,14057
70+
2019年11月08日,15,14,24,14,2019年11月08日,15366
71+
2019年11月09日,11,12,18,11,2019年11月09日,10403
72+
2019年11月10日,16,13,20,13,2019年11月10日,15611
73+
2019年11月11日,18,15,18,10,2019年11月11日,14544
74+
2019年11月12日,18,11,19,11,2019年11月12日,12009
75+
2019年11月13日,16,16,22,14,2019年11月13日,18481
76+
2019年11月14日,14,11,20,11,2019年11月14日,11876
77+
2019年11月15日,21,16,23,15,2019年11月15日,16481
78+
2019年11月16日,23,23,23,15,2019年11月16日,18562
79+
2019年11月17日,26,18,26,17,2019年11月17日,16095
80+
2019年11月18日,24,24,26,21,2019年11月18日,14052
81+
2019年11月19日,30,23,31,22,2019年11月19日,12698
82+
2019年11月20日,27,25,32,22,2019年11月20日,10097
83+
2019年11月21日,24,28,30,22,2019年11月21日,12405
84+
2019年11月22日,18,22,23,18,2019年11月22日,11883
85+
2019年11月23日,18,21,22,17,2019年11月23日,15834
86+
2019年11月24日,21,18,24,18,2019年11月24日,17172
87+
2019年11月25日,24,15,25,15,2019年11月25日,11327
88+
2019年11月26日,27,25,27,17,2019年11月26日,11876
89+
2019年11月27日,30,24,32,23,2019年11月27日,17715
90+
2019年11月28日,28,22,28,19,2019年11月28日,14520
91+
2019年11月29日,14,16,19,13,2019年11月29日,18113
92+
2019年11月30日,22,19,23,19,2019年11月30日,16670
93+
2019年12月01日,31,26,32,25,2019年12月01日,15978
94+
2019年12月02日,29,26,30,26,2019年12月02日,15367
95+
2019年12月03日,28,28,28,28,2019年12月03日,18364
96+
2019年12月04日,27,27,28,27,2019年12月04日,17550
97+
2019年12月05日,37,41,42,34,2019年12月05日,16636
98+
2019年12月06日,31,28,36,28,2019年12月06日,15326
99+
2019年12月07日,33,28,36,28,2019年12月07日,15007
100+
2019年12月08日,37,38,38,35,2019年12月08日,16018
101+
2019年12月09日,44,43,44,43,2019年12月09日,17392
102+
2019年12月10日,36,40,40,33,2019年12月10日,17550
103+
2019年12月11日,27,35,36,26,2019年12月11日,13408
104+
2019年12月12日,32,24,32,23,2019年12月12日,19170
105+
2019年12月13日,29,34,34,29,2019年12月13日,12548
106+
2019年12月14日,34,31,36,28,2019年12月14日,19605
107+
2019年12月15日,33,31,37,31,2019年12月15日,14594
108+
2019年12月16日,43,43,43,39,2019年12月16日,16895
109+
2019年12月17日,50,40,50,40,2019年12月17日,18880
110+
2019年12月18日,42,48,48,39,2019年12月18日,18207
111+
2019年12月19日,44,39,49,39,2019年12月19日,17279
112+
2019年12月20日,53,46,53,45,2019年12月20日,11028
113+
2019年12月21日,51,44,51,43,2019年12月21日,19840
114+
2019年12月22日,44,49,49,41,2019年12月22日,10863
115+
2019年12月23日,43,40,45,38,2019年12月23日,13153
116+
2019年12月24日,50,42,50,40,2019年12月24日,16929
117+
2019年12月25日,51,42,52,42,2019年12月25日,17419
118+
2019年12月26日,49,56,56,49,2019年12月26日,13232
119+
2019年12月27日,47,48,50,45,2019年12月27日,19252
120+
2019年12月28日,54,53,54,53,2019年12月28日,11631
121+
2019年12月29日,46,53,53,46,2019年12月29日,14527
122+
2019年12月30日,46,46,55,46,2019年12月30日,10600
123+
2019年12月31日,54,58,59,53,2019年12月31日,17911
124+
2020年01月01日,55,48,56,47,2020年01月01日,17827

‎src/mplfinance/_arg_validators.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import pandas as pd
33
import numpy as np
44
import datetime
5-
from mplfinance._helpers import _list_of_dict
5+
from mplfinance._helpers import _list_of_dict, _mpf_is_color_like
66
import matplotlib as mpl
77
import warnings
88

@@ -359,6 +359,25 @@ def _yscale_validator(value):
359359
return True
360360

361361

362+
def _is_marketcolor_object(obj):
363+
if not isinstance(obj,dict): return False
364+
market_colors_keys = ('candle','edge','wick','ohlc')
365+
return all([k in obj for k in market_colors_keys])
366+
367+
368+
def _mco_validator(value): # marketcolor overrides validator
369+
if isinstance(value,dict): # not yet supported, but maybe we will have other
370+
if 'colors' not in value: # kwargs related to mktcolor overrides (ex: `mco_faceonly`)
371+
raise ValueError('`marketcolor_overrides` as dict must contain `colors` key.')
372+
colors = value['colors']
373+
else:
374+
colors = value
375+
if not isinstance(colors,(list,tuple,np.ndarray)):
376+
return False
377+
return all([(c is None or
378+
_mpf_is_color_like(c) or
379+
_is_marketcolor_object(c) ) for c in colors])
380+
362381
def _check_for_external_axes(config):
363382
'''
364383
Check that all `fig` and `ax` kwargs are either ALL None,

‎src/mplfinance/_helpers.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
"""
22
Some helper functions for mplfinance.
3+
NOTE: This is the lowest level in mplfinance:
4+
This file should have NO dependencies on
5+
any other mplfinance files.
36
"""
47

58
import datetime
6-
import matplotlib.dates as mdates
9+
import matplotlib.dates as mdates
10+
import matplotlib.colors as mcolors
711
import numpy as np
812

913
def _adjust_color_brightness(color,amount=0.5):
@@ -82,3 +86,36 @@ def roundTime(dt=None, roundTo=60):
8286
seconds = (dt.replace(tzinfo=None) - dt.min).seconds
8387
rounding = (seconds+roundTo/2) // roundTo * roundTo
8488
return dt + datetime.timedelta(0,rounding-seconds,-dt.microsecond)
89+
90+
91+
def _is_uint8_rgb_or_rgba(tup):
92+
""" Deterine if rgb or rgba is in (0-255) format:
93+
Matplotlib expects rgb (and rgba) tuples to contain
94+
three (or four) floats between 0.0 and 1.0
95+
96+
Some people express rgb as tuples of three integers
97+
between 0 and 255.
98+
(In rgba, alpha is still a float from 0.0 to 1.0)
99+
"""
100+
if isinstance(tup,str): return False
101+
if not np.iterable(tup): return False
102+
L = len(tup)
103+
if L < 3 or L > 4: return False
104+
if L == 4 and (tup[3] < 0 or tup[3] > 1): return False
105+
return not any([not isinstance(v,(int,np.unsignedinteger)) or v<0 or v>255 for v in tup[0:3]])
106+
107+
def _mpf_is_color_like(c):
108+
"""Determine if an object is a color.
109+
110+
Identical to `matplotlib.colors.is_color_like()`
111+
BUT ALSO considers int (0-255) rgb and rgba colors.
112+
"""
113+
if mcolors.is_color_like(c): return True
114+
return _is_uint8_rgb_or_rgba(c)
115+
116+
def _mpf_to_rgba(c, alpha=None):
117+
cnew = c
118+
if _is_uint8_rgb_or_rgba(c) and any(e>1 for e in c[:3]):
119+
cnew = tuple([e/255. for e in c[:3]])
120+
if len(c) == 4: cnew += c[3:]
121+
return mcolors.to_rgba(cnew, alpha)

‎src/mplfinance/_styles.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import matplotlib.pyplot as plt
2-
import matplotlib.colors as mcolors
32
import copy
43
import pprint
54
import os.path as path
65

76
from mplfinance._arg_validators import _process_kwargs, _validate_vkwargs_dict
87
from mplfinance._styledata import _styles
8+
from mplfinance._helpers import _mpf_is_color_like
99

1010

1111
def _get_mpfstyle(style):
@@ -70,7 +70,7 @@ def _valid_make_mpf_style_kwargs():
7070
'Validator' : lambda value: isinstance(value,dict) },
7171

7272
'mavcolors' : { 'Default' : None,
73-
'Validator' : lambda value: isinstance(value,list) }, # TODO: all([mcolors.is_color_like(v) for v in value.values()])
73+
'Validator' : lambda value: isinstance(value,list) }, # TODO: all([_mpf_is_color_like(v) for v in value.values()])
7474

7575
'facecolor' : { 'Default' : None,
7676
'Validator' : lambda value: isinstance(value,str) },
@@ -153,10 +153,10 @@ def make_mpf_style( **kwargs ):
153153

154154
def _valid_mpf_color_spec(value):
155155
'value must be a color, "inherit"-like, or dict of colors'
156-
return ( mcolors.is_color_like(value) or
156+
return ( _mpf_is_color_like(value) or
157157
( isinstance(value,str) and value == 'inherit'[0:len(value)]) or
158158
( isinstance(value,dict) and
159-
all([mcolors.is_color_like(v) for v in value.values()])
159+
all([_mpf_is_color_like(v) for v in value.values()])
160160
)
161161
)
162162

@@ -190,13 +190,13 @@ def _valid_mpf_style(value):
190190
def _valid_make_marketcolors_kwargs():
191191
vkwargs = {
192192
'up' : { 'Default' : None,
193-
'Validator' : lambda value: mcolors.is_color_like(value) },
193+
'Validator' : lambda value: _mpf_is_color_like(value) },
194194

195195
'down' : { 'Default' : None,
196-
'Validator' : lambda value: mcolors.is_color_like(value) },
196+
'Validator' : lambda value: _mpf_is_color_like(value) },
197197

198198
'hollow' : { 'Default' : None,
199-
'Validator' : lambda value: mcolors.is_color_like(value) },
199+
'Validator' : lambda value: _mpf_is_color_like(value) },
200200

201201
'alpha' : { 'Default' : None,
202202
'Validator' : lambda value: ( isinstance(value,float) and
@@ -208,17 +208,17 @@ def _valid_make_marketcolors_kwargs():
208208
'wick' : { 'Default' : None,
209209
'Validator' : lambda value: isinstance(value,dict)
210210
or isinstance(value,str)
211-
or mcolors.is_color_like(value) },
211+
or _mpf_is_color_like(value) },
212212

213213
'ohlc' : { 'Default' : None,
214214
'Validator' : lambda value: isinstance(value,dict)
215215
or isinstance(value,str)
216-
or mcolors.is_color_like(value) },
216+
or _mpf_is_color_like(value) },
217217

218218
'volume' : { 'Default' : None,
219219
'Validator' : lambda value: isinstance(value,dict)
220220
or isinstance(value,str)
221-
or mcolors.is_color_like(value) },
221+
or _mpf_is_color_like(value) },
222222

223223
'vcdopcod' : { 'Default' : False,
224224
'Validator' : lambda value: isinstance(value,bool) },
@@ -282,7 +282,7 @@ def _check_and_set_mktcolor(candle,**kwarg):
282282
else:
283283
colors = dict(up=value, down=value)
284284
for updown in ['up','down']:
285-
if not mcolors.is_color_like(colors[updown]):
285+
if not _mpf_is_color_like(colors[updown]):
286286
err = f'NOT is_color_like() for {key}[\'{updown}\'] = {colors[updown]}'
287287
raise ValueError(err)
288288
return colors

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /