siat 2.14.1__py3-none-any.whl → 3.0.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.
siat/grafix.py CHANGED
@@ -21,7 +21,8 @@ from siat.translate import *
21
21
  import pandas as pd
22
22
  #==============================================================================
23
23
  import matplotlib.pyplot as plt
24
-
24
+ import matplotlib.dates as mdate
25
+ #==============================================================================
25
26
  #统一设定绘制的图片大小:数值为英寸,1英寸=100像素
26
27
  plt.rcParams['figure.figsize']=(12.8,7.2)
27
28
  plt.rcParams['figure.dpi']=300
@@ -69,6 +70,8 @@ plt.rcParams['axes.unicode_minus'] = False
69
70
  #==============================================================================
70
71
  if __name__ =="__main__":
71
72
  df0=get_price('000001.SS','2023-1-1','2024-3-22')
73
+ df0=get_price('sz149995','2020-1-1','2024-3-31')
74
+ df0,_=get_price_1ticker('sz149976',fromdate='2024-1-1',todate='2024-4-6',fill=True)
72
75
 
73
76
  colname='Close'
74
77
  collabel='Close'
@@ -84,49 +87,45 @@ if __name__ =="__main__":
84
87
  date_range=False
85
88
  date_freq=False
86
89
  date_fmt='%Y-%m-%d'
87
- mark_top=1
88
- mark_bottom=1
90
+ mark_top=True
91
+ mark_bottom=True
89
92
 
90
- plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,mark_top=1,mark_bottom=1)
93
+ plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,mark_top=True,mark_bottom=True)
91
94
 
92
95
  def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
93
96
  power=0,zeroline=False,average_value=False, \
94
97
  resample_freq='H',loc='best', \
95
98
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
96
- mark_top=0,mark_bottom=0,mark_end=True):
99
+ mark_top=True,mark_bottom=True,mark_end=True):
97
100
  """
98
101
  功能:绘制折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
99
102
  假定:数据表有索引,且已经按照索引排序
100
103
  输入:数据表df,数据表中的列名colname,列名的标签collabel;y轴标签ylabeltxt;
101
104
  标题titletxt,脚注footnote;是否在图中标记数据datatag;趋势图的多项式次数power
102
- mark_top,mark_bottom:标记最高最低点的个数
105
+ mark_top,mark_bottom:是否标记最高最低点
103
106
  输出:折线图
104
107
  返回值:无
105
108
  注意:需要日期类型作为df索引
106
109
  """
110
+
107
111
  #空值判断
108
112
  if len(df0) ==0:
109
113
  print (" #Warning(plot_line): no data to plot.")
110
114
  return
111
115
 
112
- #插值平滑
116
+ #插值平滑:未填充时
117
+ #if 'filled' not in list(df0):
113
118
  try:
114
119
  df0x=df0[[colname]].astype('float')
115
120
  df=df_smooth_manual(df0x,resample_freq=resample_freq)
116
121
  except:
117
122
  df=df0
123
+ #else: df=df0
118
124
 
119
125
  #先绘制折线图
120
- """
121
- plt.plot(df.index,df[colname],'-',label=collabel, \
122
- linestyle='-',color='blue', linewidth=1, \
123
- marker='o',markersize=2)
124
- """
125
-
126
- import matplotlib.dates as mdate
127
126
  date_start=df.index[0]
128
127
  date_end=df.index[-1]
129
- ax=plt.gca()
128
+ ax=plt.gca()
130
129
 
131
130
  if date_range and not date_freq:
132
131
  ax.xaxis.set_major_formatter(mdate.DateFormatter(date_fmt))
@@ -144,42 +143,65 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
144
143
  ylabeltxt=''
145
144
 
146
145
  lwadjust=linewidth_adjust(df)
146
+
147
+ #if 'filled' not in list(df):
147
148
  plt.plot(df.index,df[colname],'-',label=collabel, \
148
149
  linestyle='-',color='blue', linewidth=lwadjust)
150
+ """
151
+ else:
152
+ #区分实际有数据部分和填充部分
153
+ df_raw=df[df['filled'] == False] #原有数据
154
+ df_filled=df[df['filled'] != False] #填充的数据
155
+
156
+ plt.plot(df_filled.index,df_filled[colname],'-',label=collabel, \
157
+ linestyle=':',color='black', linewidth=lwadjust)
149
158
 
159
+ plt.plot(df_raw.index,df_raw[colname],'-',label=collabel, \
160
+ linestyle='-',color='blue', linewidth=lwadjust)
161
+ """
150
162
  haveLegend=True
151
163
  if collabel == '':
152
164
  haveLegend=False
153
165
 
154
166
  #绘制数据标签
155
167
  if datatag:
168
+ mark_top=False; mark_bottom=False; mark_end=False
156
169
  for x, y in zip(df.index, df[colname]):
157
170
  plt.text(x,y*1.001,'%.2f' % y,ha='center',va='bottom',color='black')
158
171
 
159
172
  #标记最高点/最低点
160
- if mark_top > 0 or mark_bottom > 0:
173
+ if mark_top or mark_bottom:
161
174
  df_mark=df[[colname]].copy() #避免影响原df
162
175
  df_mark.sort_values(by=colname,ascending=False,inplace=True)
163
176
 
164
177
  high_poit=df_mark[colname].head(1).values[0]
165
178
  low_poit=df_mark[colname].tail(1).values[0]
166
179
  high_low=high_poit - low_poit
167
- if mark_top > 0:
168
- df_mark_top=df_mark[:mark_top]
180
+ if mark_top:
181
+ df_mark_top=df_mark[:1]
169
182
  for x, y in zip(df_mark_top.index, df_mark_top[colname]):
170
183
  #plt.text(x,y+0.1,'%.2f' % y,ha='center',va='bottom',color='red')
171
- y1=round(y+high_low*0.01,2)
184
+ #y1=round(y+high_low*0.01,2)
185
+ y1=y+high_low*0.01
186
+ #s='%.0f' if y >= 100 else '%.2f'
187
+ s='%.0f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.3f'
188
+ plt.text(x,y1,s % y,ha='right',va='bottom',color='red')
189
+ """
172
190
  s='%.0f' if y >= 100 else '%.2f'
173
- plt.text(x,y1,s % y,ha='center',va='bottom',color='red')
191
+ plt.text(x,y,s % y,ha='right',va='bottom',color='red')
192
+ """
174
193
  plt.scatter(x,y, color='red',marker='8',s=70)
175
194
 
176
- if mark_bottom > 0:
177
- df_mark_bottom=df_mark[-mark_bottom:]
195
+ if mark_bottom:
196
+ df_mark_bottom=df_mark[-1:]
178
197
  for x, y in zip(df_mark_bottom.index, df_mark_bottom[colname]):
179
198
  #plt.text(x,y-0.1,'%.2f' % y,ha='center',va='bottom',color='black')
180
- y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
181
- s='%.0f' if y >= 100 else '%.2f'
182
- plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
199
+ #y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
200
+ y1=y-high_low*0.050 #标记位置对应y1的底部
201
+ #s='%.0f' if y >= 100 else '%.2f'
202
+ s='%.0f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.3f'
203
+ #plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
204
+ plt.text(x,y1,s % y,ha='right',va='bottom',color='seagreen')
183
205
  plt.scatter(x,y, color='seagreen',marker='8',s=70)
184
206
 
185
207
  #标记曲线末端数值
@@ -188,7 +210,8 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
188
210
  y_end = df_end[colname].min() # 末端的y坐标
189
211
  x_end = df_end[colname].idxmin() # 末端值的x坐标
190
212
 
191
- y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
213
+ #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
214
+ y1=str(int(y_end)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 10 else str(round(y_end,3))
192
215
  plt.annotate(text=' '+y1,
193
216
  xy=(x_end, y_end),
194
217
  xytext=(x_end, y_end),fontsize=annotate_size)
@@ -197,8 +220,9 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
197
220
  if isinstance(zeroline,bool):#若zeroline为True
198
221
  if zeroline:
199
222
  hline=0
200
- plt.axhline(y=hline,ls=":",c="green",linewidth=2,label="零线")
201
- haveLegend=True
223
+ #plt.axhline(y=hline,ls=":",c="green",linewidth=2,label="零线")
224
+ plt.axhline(y=hline,ls=":",c="black",linewidth=2,label='')
225
+ haveLegend=False
202
226
  else:
203
227
  if isinstance(zeroline,float) or isinstance(zeroline,int):
204
228
  hline=zeroline
@@ -210,16 +234,16 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
210
234
  av=df[colname].mean()
211
235
  plt.axhline(y=av,ls="dashed",c="blueviolet",linewidth=2,label="均值")
212
236
  haveLegend=True
213
- footnote=footnote + ",均值"+str(round(av,2))
237
+ #av=str(round(av,2)) if av < 100 else str(int(av))
238
+ av=str(int(av)) if abs(av) >= 100 else str(round(av,2)) if abs(av) >= 10 else str(round(av,3))
239
+ #footnote=footnote + ",均值"+av
240
+ footnote="注:期间均值"+av+";"+footnote
214
241
 
215
242
  #绘制趋势线
216
243
  #print("--Debug(plot_line): power=",power)
217
244
  if power > 0:
218
- lang=check_language()
219
- trend_txt='趋势线'
220
- #trend_txt=''
221
- if lang == 'English':
222
- trend_txt='Trend line'
245
+ trend_txt=text_lang('趋势线','Trend line')
246
+
223
247
  try:
224
248
  #生成行号,借此将横轴的日期数量化,以便拟合
225
249
  df['id']=range(len(df))
@@ -231,13 +255,16 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
231
255
  plt.plot(df.index, f(df.id),"r--", label=trend_txt,linewidth=1)
232
256
  haveLegend=True
233
257
  except:
234
- print(" Warning(plot_line): failed to converge trend line, try a smaller power.")
258
+ print(" #Warning(plot_line): failed to converge trend line, try a smaller power.")
235
259
 
236
260
  if ylabeltxt != '' or average_value or isinstance(zeroline,bool):
237
261
  if haveLegend:
238
262
  plt.legend(loc=loc,fontsize=legend_txt_size)
239
263
 
240
264
  plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
265
+
266
+ if '基金' in titletxt and '收盘价' in ylabeltxt:
267
+ ylabeltxt=ylabeltxt.replace('收盘价','单位净值')
241
268
 
242
269
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
243
270
  plt.xlabel(footnote,fontsize=xlabel_txt_size)
@@ -248,8 +275,6 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
248
275
 
249
276
  return
250
277
 
251
- if __name__ =="__main__":
252
- plot_line(df,'Close',"收盘价","价格","万科股票","数据来源:新浪/stooq",power=4)
253
278
 
254
279
  #==============================================================================
255
280
  if __name__ =="__main__":
@@ -364,11 +389,12 @@ def plot2_line2(df1,ticker1,colname1,label1, \
364
389
 
365
390
  def plot_line2_coaxial(df01,ticker1,colname1,label1, \
366
391
  df02,ticker2,colname2,label2, \
367
- ylabeltxt,titletxt,footnote, \
368
- power=0,datatag1=False,datatag2=False,zeroline=False, \
369
- yline=999,xline=999,resample_freq='H', \
370
- loc1='best',loc2='best', \
371
- color1='red',color2='blue'):
392
+ ylabeltxt,titletxt,footnote, \
393
+ power=0,datatag1=False,datatag2=False,zeroline=False, \
394
+ yline=999,xline=999,resample_freq='H', \
395
+ loc1='best',loc2='best', \
396
+ color1='red',color2='blue', \
397
+ ticker_type='auto'):
372
398
  """
373
399
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
374
400
  假定:数据表有索引,且已经按照索引排序
@@ -392,19 +418,24 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
392
418
  df2=df_smooth_manual(df02x,resample_freq=resample_freq)
393
419
  except:
394
420
  df2=df02
421
+
422
+ #预处理ticker_type
423
+ ticker_type_list=ticker_type_preprocess_mticker_mixed([ticker1,ticker2],ticker_type)
424
+
395
425
  #证券1:先绘制折线图
396
426
 
397
427
  if ticker1 == '':
398
428
  label1txt=label1
399
429
  else:
400
430
  if label1 == '':
401
- label1txt=codetranslate(ticker1)
431
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
402
432
  else:
403
- label1txt=codetranslate(ticker1)+'('+label1+')'
433
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+'('+label1+')'
404
434
 
405
435
  lwadjust=linewidth_adjust(df1)
406
436
  plt.plot(df1.index,df1[colname1],'-',label=label1txt, \
407
437
  linestyle='-',linewidth=lwadjust,color=color1)
438
+
408
439
  #证券1:绘制数据标签
409
440
  if datatag1:
410
441
  for x, y in zip(df1.index, df1[colname1]):
@@ -424,10 +455,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
424
455
 
425
456
  #绘证券1:制趋势线
426
457
  if power > 0:
427
- lang=check_language()
428
- trend_txt='趋势线'
429
- if lang == 'English':
430
- trend_txt='Trend line'
458
+ trend_txt=text_lang('趋势线','Trend line')
431
459
 
432
460
  try:
433
461
  #生成行号,借此将横轴的日期数量化,以便拟合
@@ -441,7 +469,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
441
469
  if ticker1 == '':
442
470
  label1txt=''
443
471
  else:
444
- label1txt=codetranslate(ticker1)+"("+trend_txt+")"
472
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
445
473
 
446
474
  #plt.plot(df1.index, f(df1.id),"g--", label=label1txt,linewidth=1)
447
475
  plt.plot(df1.index, f(df1.id),"g--", label='',linewidth=1)
@@ -452,9 +480,9 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
452
480
  label2txt=label2
453
481
  else:
454
482
  if label2 == '':
455
- label2txt=codetranslate(ticker2)
483
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
456
484
  else:
457
- label2txt=codetranslate(ticker2)+'('+label2+')'
485
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+'('+label2+')'
458
486
 
459
487
  lwadjust=linewidth_adjust(df2)
460
488
  plt.plot(df2.index,df2[colname2],'-',label=label2txt, \
@@ -483,7 +511,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
483
511
  if ticker2 == '':
484
512
  label2txt=''
485
513
  else:
486
- label2txt=codetranslate(ticker2)+"("+trend_txt+")"
514
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
487
515
 
488
516
  #plt.plot(df2.index, f(df2.id),"r--", label=label2txt,linewidth=1)
489
517
  plt.plot(df2.index, f(df2.id),"r--", label='',linewidth=1)
@@ -527,7 +555,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
527
555
  yline=999,xline=999,resample_freq='H', \
528
556
  loc1='best',loc2='best', \
529
557
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
530
- color1='red',color2='blue'):
558
+ color1='red',color2='blue',ticker_type='auto'):
531
559
  """
532
560
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
533
561
  假定:数据表有索引,且已经按照索引排序
@@ -551,17 +579,19 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
551
579
  df2=df_smooth_manual(df02x,resample_freq=resample_freq)
552
580
  except:
553
581
  df2=df02
582
+
583
+ #预处理ticker_type
584
+ ticker_type_list=ticker_type_preprocess_mticker_mixed([ticker1,ticker2],ticker_type)
585
+
554
586
  #证券1:先绘制折线图
555
-
556
587
  if ticker1 == '':
557
588
  label1txt=label1
558
589
  else:
559
590
  if label1 == '':
560
- label1txt=codetranslate(ticker1)
591
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
561
592
  else:
562
- label1txt=codetranslate(ticker1)+'('+label1+')'
593
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+'('+label1+')'
563
594
 
564
- import matplotlib.dates as mdate
565
595
  ax=plt.gca()
566
596
  date_start=df1.index[0]
567
597
  date_end=df1.index[-1]
@@ -614,7 +644,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
614
644
  if ticker1 == '':
615
645
  label1txt=''
616
646
  else:
617
- label1txt=codetranslate(ticker1)+"("+trend_txt+")"
647
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
618
648
  plt.plot(df1.index, f(df1.id),"g--", label=label1txt,linewidth=1)
619
649
  except: pass
620
650
 
@@ -623,9 +653,9 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
623
653
  label2txt=label2
624
654
  else:
625
655
  if label2 == '':
626
- label2txt=codetranslate(ticker2)
656
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
627
657
  else:
628
- label2txt=codetranslate(ticker2)+'('+label2+')'
658
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+'('+label2+')'
629
659
 
630
660
  date_start=df2.index[0]
631
661
  date_end=df2.index[-1]
@@ -666,7 +696,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
666
696
  if ticker2 == '':
667
697
  label2txt=''
668
698
  else:
669
- label2txt=codetranslate(ticker2)+"("+trend_txt+")"
699
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
670
700
  plt.plot(df2.index, f(df2.id),"r--", label=label2txt,linewidth=1)
671
701
  except: pass
672
702
 
@@ -687,7 +717,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
687
717
  df02,ticker2,colname2,label2, \
688
718
  titletxt,footnote,power=0,datatag1=False,datatag2=False, \
689
719
  resample_freq='H',loc1='upper left',loc2='lower left', \
690
- color1='red',color2='blue'):
720
+ color1='red',color2='blue',ticker_type='auto'):
691
721
  """
692
722
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
693
723
  假定:数据表有索引,且已经按照索引排序
@@ -712,9 +742,11 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
712
742
  df2=df_smooth_manual(df02x,resample_freq=resample_freq)
713
743
  except:
714
744
  df2=df02
715
-
745
+
746
+ #预处理ticker_type
747
+ ticker_type_list=ticker_type_preprocess_mticker_mixed([ticker1,ticker2],ticker_type)
748
+
716
749
  #证券1:绘制折线图,双坐标轴
717
- import matplotlib.dates as mdates
718
750
  fig = plt.figure()
719
751
  ax = fig.add_subplot(111)
720
752
 
@@ -722,9 +754,9 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
722
754
  label1txt=label1
723
755
  else:
724
756
  if label1 == '':
725
- label1txt=codetranslate(ticker1)
757
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
726
758
  else:
727
- label1txt=codetranslate(ticker1)+'('+label1+')'
759
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+'('+label1+')'
728
760
 
729
761
  lwadjust=linewidth_adjust(df1)
730
762
  ax.plot(df1.index,df1[colname1],'-',label=label1txt, \
@@ -752,7 +784,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
752
784
  if ticker1 == '':
753
785
  label1txt=''
754
786
  else:
755
- label1txt=codetranslate(ticker1)+"("+trend_txt+")"
787
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
756
788
  ax.plot(df1.index, f(df1.id),"r--", label=label1txt,linewidth=1)
757
789
 
758
790
  #绘证券2:建立第二y轴
@@ -762,9 +794,9 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
762
794
  label2txt=label2
763
795
  else:
764
796
  if label2 == '':
765
- label2txt=codetranslate(ticker2)
797
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
766
798
  else:
767
- label2txt=codetranslate(ticker2)+'('+label2+')'
799
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+'('+label2+')'
768
800
 
769
801
  lwadjust=linewidth_adjust(df2)
770
802
  ax2.plot(df2.index,df2[colname2],'-',label=label2txt, \
@@ -792,7 +824,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
792
824
  if ticker2 == '':
793
825
  label2txt=''
794
826
  else:
795
- label2txt=codetranslate(ticker2)+"("+trend_txt+")"
827
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
796
828
  ax2.plot(df2.index, f(df2.id),"c--", label=label2txt,linewidth=1)
797
829
 
798
830
  ax.set_xlabel(footnote,fontsize=xlabel_txt_size)
@@ -801,9 +833,9 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
801
833
  label1txt=label1
802
834
  else:
803
835
  if label1 == "":
804
- label1txt=codetranslate(ticker1)
836
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
805
837
  else:
806
- label1txt=label1+'('+codetranslate(ticker1)+')'
838
+ label1txt=label1+'('+ticker_name(ticker1,ticker_type_list[0])+')'
807
839
  ax.set_ylabel(label1txt,fontsize=ylabel_txt_size)
808
840
  ax.legend(loc=loc1,fontsize=legend_txt_size)
809
841
 
@@ -811,9 +843,9 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
811
843
  label2txt=label2
812
844
  else:
813
845
  if label2 == "":
814
- label2txt=codetranslate(ticker2)
846
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
815
847
  else:
816
- label2txt=label2+'('+codetranslate(ticker2)+')'
848
+ label2txt=label2+'('+ticker_name(ticker2,ticker_type_list[1])+')'
817
849
  ax2.set_ylabel(label2txt,fontsize=ylabel_txt_size)
818
850
  ax2.legend(loc=loc2,fontsize=legend_txt_size)
819
851
 
@@ -847,7 +879,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
847
879
  titletxt,footnote,power=0,datatag1=False,datatag2=False, \
848
880
  resample_freq='H',loc1='upper left',loc2='lower left', \
849
881
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
850
- color1='red',color2='blue'):
882
+ color1='red',color2='blue',ticker_type='auto'):
851
883
  """
852
884
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
853
885
  假定:数据表有索引,且已经按照索引排序
@@ -872,9 +904,11 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
872
904
  df2=df_smooth_manual(df02x,resample_freq=resample_freq)
873
905
  except:
874
906
  df2=df02
907
+
908
+ #预处理ticker_type
909
+ ticker_type_list=ticker_type_preprocess_mticker_mixed([ticker1,ticker2],ticker_type)
875
910
 
876
911
  #证券1:绘制折线图,双坐标轴
877
- import matplotlib.dates as mdate
878
912
  fig = plt.figure()
879
913
  ax = fig.add_subplot(111)
880
914
 
@@ -882,9 +916,9 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
882
916
  label1txt=label1
883
917
  else:
884
918
  if label1 == '':
885
- label1txt=codetranslate(ticker1)
919
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
886
920
  else:
887
- label1txt=codetranslate(ticker1)+'('+label1+')'
921
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+'('+label1+')'
888
922
 
889
923
  date_start=df1.index[0]
890
924
  date_end=df1.index[-1]
@@ -924,7 +958,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
924
958
  if ticker1 == '':
925
959
  label1txt=''
926
960
  else:
927
- label1txt=codetranslate(ticker1)+"("+trend_txt+")"
961
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
928
962
  ax.plot(df1.index, f(df1.id),"r--", label=label1txt,linewidth=1)
929
963
 
930
964
  #绘证券2:建立第二y轴
@@ -934,9 +968,9 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
934
968
  label2txt=label2
935
969
  else:
936
970
  if label2 == '':
937
- label2txt=codetranslate(ticker2)
971
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
938
972
  else:
939
- label2txt=codetranslate(ticker2)+'('+label2+')'
973
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+'('+label2+')'
940
974
 
941
975
  date_start=df2.index[0]
942
976
  date_end=df2.index[-1]
@@ -976,7 +1010,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
976
1010
  if ticker2 == '':
977
1011
  label2txt=''
978
1012
  else:
979
- label2txt=codetranslate(ticker2)+"("+trend_txt+")"
1013
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
980
1014
 
981
1015
  ax2.plot(df2.index, f(df2.id),"c--", label=label2txt,linewidth=1)
982
1016
 
@@ -986,9 +1020,9 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
986
1020
  label1txt=label1
987
1021
  else:
988
1022
  if label1 == "":
989
- label1txt=codetranslate(ticker1)
1023
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
990
1024
  else:
991
- label1txt=label1+'('+codetranslate(ticker1)+')'
1025
+ label1txt=label1+'('+ticker_name(ticker1,ticker_type_list[0])+')'
992
1026
  ax.set_ylabel(label1txt,fontsize=ylabel_txt_size)
993
1027
  ax.legend(loc=loc1,fontsize=legend_txt_size)
994
1028
 
@@ -996,9 +1030,9 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
996
1030
  label2txt=label2
997
1031
  else:
998
1032
  if label2 == "":
999
- label2txt=codetranslate(ticker2)
1033
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
1000
1034
  else:
1001
- label2txt=label2+'('+codetranslate(ticker2)+')'
1035
+ label2txt=label2+'('+ticker_name(ticker2,ticker_type_list[1])+')'
1002
1036
  ax2.set_ylabel(label2txt,fontsize=ylabel_txt_size)
1003
1037
  ax2.legend(loc=loc2,fontsize=legend_txt_size)
1004
1038
 
@@ -1016,7 +1050,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1016
1050
  def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1017
1051
  data_label=True,resample_freq='H',smooth=True,linewidth=1.5, \
1018
1052
  loc='best',annotate=False,annotate_value=False,plus_sign=False, \
1019
- mark_top=0,mark_bottom=0,mark_end=False):
1053
+ mark_top=False,mark_bottom=False,mark_end=False,ticker_type='auto'):
1020
1054
  """
1021
1055
  函数功能:根据df的内容绘制折线图
1022
1056
  输入参数:
@@ -1103,63 +1137,80 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1103
1137
 
1104
1138
  #plt.plot(dfg,label=c,linewidth=linewidth,ls=lsc,marker=mkc,markersize=3)
1105
1139
  lwadjust=linewidth_adjust(dfg)
1140
+
1141
+ """
1106
1142
  if not annotate:
1107
- """
1108
- 注意:许多传入的df字段名已经不是证券代码,此处调用codetranslate将会导致
1109
- 股票名称字典重新下载,耗费时间,且出现黄条。
1110
- 建议:在调用draw_lines之前,先调用codetranslate,将证券代码翻译为证券名称。
1111
- 本函数仅负责绘图,不负责翻译证券名称。
1112
- """
1143
+
1144
+ #注意:许多传入的df字段名已经不是证券代码,此处调用codetranslate将会导致
1145
+ #股票名称字典重新下载,耗费时间,且出现黄条。
1146
+ #建议:在调用draw_lines之前,先调用codetranslate,将证券代码翻译为证券名称。
1147
+ #本函数仅负责绘图,不负责翻译证券名称。
1148
+
1113
1149
  #plt.plot(dfg,label=codetranslate(c),linewidth=linewidth,ls=lsc,marker=mkc,markersize=3)
1114
1150
  plt.plot(dfg,label=c,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1115
1151
  else:
1116
1152
  #plt.plot(dfg[c],label=codetranslate(c),linewidth=linewidth,ls=lsc,marker=mkc,markersize=3)
1117
1153
  #plt.plot(dfg,label=codetranslate(c),linewidth=linewidth,ls=lsc,marker=mkc,markersize=3)
1118
1154
  plt.plot(dfg,label=c,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1119
-
1155
+ """
1156
+ plt.plot(dfg,label=c,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1157
+ lines = plt.gca().lines
1158
+ last_line_color = lines[-1].get_color()
1159
+
1160
+ if annotate:
1120
1161
  df_end=dfg.tail(1)
1121
1162
  # df_end[c]必须为数值类型,否则可能出错
1122
1163
  y_end = df_end[c].min() # 末端的y坐标
1123
1164
  x_end = df_end[c].idxmin() # 末端值的x坐标
1124
1165
 
1125
1166
  if annotate_value: #在标记曲线名称的同时标记其末端数值
1126
- y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1167
+ #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1168
+ y1=str(int(y_end)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 10 else str(round(y_end,3))
1127
1169
  plt.annotate(text=c+':'+y1,
1128
- xy=(x_end, y_end),
1129
- xytext=(x_end, y_end),fontsize=annotate_size)
1170
+ xy=(x_end, y_end),
1171
+ xytext=(x_end, y_end),fontsize=annotate_size,
1172
+ color=last_line_color)
1130
1173
  else:
1131
1174
  plt.annotate(text=c,
1132
- xy=(x_end, y_end),
1133
- #xytext=(x_end, y_end),fontsize=9)
1134
- xytext=(x_end, y_end),fontsize=annotate_size)
1175
+ xy=(x_end, y_end),
1176
+ #xytext=(x_end, y_end),fontsize=9)
1177
+ xytext=(x_end, y_end),fontsize=annotate_size,
1178
+ color=last_line_color)
1135
1179
 
1136
1180
  #plt.plot(df[c],label=c,linewidth=1.5,marker=mkc,markersize=3)
1137
1181
  #为折线加数据标签
1138
1182
  if data_label==True:
1183
+ mark_top=False; mark_bottom=False; mark_end=False
1139
1184
  for a,b in zip(dfg.index,df2[c]):
1140
1185
  plt.text(a,b+0.02,str(round(b,2)), \
1141
1186
  ha='center',va='bottom',fontsize=7)
1142
1187
 
1143
1188
  #标记最高点/最低点
1144
- if mark_top > 0 or mark_bottom > 0:
1189
+ if mark_top or mark_bottom:
1145
1190
  df_mark=dfg[[c]].copy() #避免影响原df
1146
1191
  df_mark.dropna(inplace=True)
1147
1192
  df_mark.sort_values(by=c,ascending=False,inplace=True)
1148
1193
 
1149
- if mark_top > 0:
1150
- df_mark_top=df_mark[:mark_top]
1194
+ if mark_top:
1195
+ df_mark_top=df_mark[:1]
1151
1196
  for x, y in zip(df_mark_top.index, df_mark_top[c]):
1152
- y1=round(y+high_low*0.01,2)
1153
- s='%.0f' if y >= 100 else '%.2f'
1154
- plt.text(x,y1,s % y,ha='center',va='bottom',color='red')
1197
+ #y1=round(y+high_low*0.01,2)
1198
+ y1=y+high_low*0.01
1199
+ #s='%.0f' if y >= 100 else '%.2f'
1200
+ s='%.0f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.3f'
1201
+ #plt.text(x,y1,s % y,ha='center',va='bottom',color='red')
1202
+ plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
1155
1203
  plt.scatter(x,y, color='red',marker='8',s=70)
1156
1204
 
1157
- if mark_bottom > 0:
1158
- df_mark_bottom=df_mark[-mark_bottom:]
1205
+ if mark_bottom:
1206
+ df_mark_bottom=df_mark[-1:]
1159
1207
  for x, y in zip(df_mark_bottom.index, df_mark_bottom[c]):
1160
- y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
1161
- s='%.0f' if y >= 100 else '%.2f'
1162
- plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
1208
+ #y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
1209
+ y1=y-high_low*0.050 #标记位置对应y1的底部
1210
+ #s='%.0f' if y >= 100 else '%.2f'
1211
+ s='%.0f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.3f'
1212
+ #plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
1213
+ plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
1163
1214
  plt.scatter(x,y, color='seagreen',marker='8',s=70)
1164
1215
 
1165
1216
  #标记曲线末端数值
@@ -1168,10 +1219,12 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1168
1219
  y_end = df_end[c].min() # 末端的y坐标
1169
1220
  x_end = df_end[c].idxmin() # 末端值的x坐标
1170
1221
 
1171
- y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1222
+ #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1223
+ y1=str(int(y_end)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 10 else str(round(y_end,3))
1172
1224
  plt.annotate(text=' '+y1,
1173
1225
  xy=(x_end, y_end),
1174
- xytext=(x_end, y_end),fontsize=annotate_size)
1226
+ xytext=(x_end, y_end),fontsize=annotate_size,
1227
+ color=last_line_color)
1175
1228
 
1176
1229
 
1177
1230
  #绘制水平辅助线
@@ -1218,7 +1271,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1218
1271
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
1219
1272
  colorlist=[],lslist=[],lwlist=[], \
1220
1273
  band_area='',loc='best',annotate=False,annotate_value=False, \
1221
- mark_top=0,mark_bottom=0,mark_end=False):
1274
+ mark_top=False,mark_bottom=False,mark_end=False):
1222
1275
  """
1223
1276
  函数功能:根据df的内容绘制折线图
1224
1277
  输入参数:
@@ -1266,7 +1319,6 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1266
1319
  high_low=dfmax - dfmin
1267
1320
 
1268
1321
  #定义横轴标签:显示完整开始、结束日期
1269
- import matplotlib.dates as mdate
1270
1322
  ax=plt.gca()
1271
1323
  date_start=df.index[0]
1272
1324
  date_end=df.index[-1]
@@ -1294,35 +1346,44 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1294
1346
  except:
1295
1347
  lwadjust=linewidth_adjust(df)
1296
1348
  plt.plot(df[c],label=c,linewidth=lwadjust)
1349
+ lines = plt.gca().lines; last_line_color = lines[-1].get_color()
1297
1350
  else:
1298
1351
  plt.plot(df[c],label=c,linewidth=llw,ls=lls,color=lcolor)
1352
+ lines = plt.gca().lines; last_line_color = lines[-1].get_color()
1299
1353
 
1300
1354
  #为折线加数据标签
1301
1355
  if data_label==True:
1356
+ mark_top=False; mark_bottom=False; mark_end=False
1302
1357
  for a,b in zip(df.index,df[c]):
1303
1358
  plt.text(a,b+0.02,str(round(b,2)), \
1304
1359
  ha='center',va='bottom',fontsize=7)
1305
1360
 
1306
1361
  #标记最高点/最低点
1307
- if mark_top > 0 or mark_bottom > 0:
1362
+ if mark_top or mark_bottom:
1308
1363
  df_mark=df[[c]].copy() #避免影响原df
1309
1364
  df_mark.dropna(inplace=True)
1310
1365
  df_mark.sort_values(by=c,ascending=False,inplace=True)
1311
1366
 
1312
- if mark_top > 0:
1313
- df_mark_top=df_mark[:mark_top]
1367
+ if mark_top:
1368
+ df_mark_top=df_mark[:1]
1314
1369
  for x, y in zip(df_mark_top.index, df_mark_top[c]):
1315
- y1=round(y+high_low*0.01,2)
1316
- s='%.0f' if y >= 100 else '%.2f'
1317
- plt.text(x,y1,s % y,ha='center',va='bottom',color='red')
1370
+ #y1=round(y+high_low*0.01,2)
1371
+ y1=y+high_low*0.01
1372
+ #s='%.0f' if y >= 100 else '%.2f'
1373
+ s='%.0f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.3f'
1374
+ #plt.text(x,y1,s % y,ha='center',va='bottom',color='red')
1375
+ plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
1318
1376
  plt.scatter(x,y, color='red',marker='8',s=70)
1319
1377
 
1320
- if mark_bottom > 0:
1321
- df_mark_bottom=df_mark[-mark_bottom:]
1378
+ if mark_bottom:
1379
+ df_mark_bottom=df_mark[-1:]
1322
1380
  for x, y in zip(df_mark_bottom.index, df_mark_bottom[c]):
1323
- y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
1324
- s='%.0f' if y >= 100 else '%.2f'
1325
- plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
1381
+ #y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
1382
+ y1=y-high_low*0.050 #标记位置对应y1的底部
1383
+ #s='%.0f' if y >= 100 else '%.2f'
1384
+ s='%.0f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.3f'
1385
+ #plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
1386
+ plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
1326
1387
  plt.scatter(x,y, color='seagreen',marker='8',s=70)
1327
1388
 
1328
1389
  #曲线末端标记:不建议用于布林带
@@ -1332,14 +1393,17 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1332
1393
  x_end = df_end[c].idxmin() # 末端值的x坐标
1333
1394
 
1334
1395
  if annotate_value: #在标记曲线名称的同时标记其末端数值
1335
- y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1396
+ #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1397
+ y1=str(int(y_end)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 10 else str(round(y_end,3))
1336
1398
  plt.annotate(text=c+':'+y1,
1337
1399
  xy=(x_end, y_end),
1338
- xytext=(x_end, y_end),fontsize=annotate_size)
1400
+ xytext=(x_end, y_end),fontsize=annotate_size,
1401
+ color=last_line_color)
1339
1402
  else:
1340
1403
  plt.annotate(text=c,
1341
1404
  xy=(x_end, y_end),
1342
- xytext=(x_end, y_end),fontsize=annotate_size)
1405
+ xytext=(x_end, y_end),fontsize=annotate_size,
1406
+ color=last_line_color)
1343
1407
 
1344
1408
  #处理布林带的mark_end,仅标记上中下线
1345
1409
  if mark_end & (c in collist3):
@@ -1347,10 +1411,12 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1347
1411
  y_end = df_end[c].min() # 末端的y坐标
1348
1412
  x_end = df_end[c].idxmin() # 末端值的x坐标
1349
1413
 
1350
- y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1414
+ #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1415
+ y1=str(int(y_end)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 10 else str(round(y_end,3))
1351
1416
  plt.annotate(text=y1,
1352
1417
  xy=(x_end, y_end),
1353
- xytext=(x_end, y_end),fontsize=annotate_size)
1418
+ xytext=(x_end, y_end),fontsize=annotate_size,
1419
+ color=last_line_color)
1354
1420
 
1355
1421
  #绘制带状区域
1356
1422
  if band_area != '' and isinstance(band_area,list) and len(band_area)>=2:
@@ -1545,7 +1611,6 @@ def plot_2lines(df01,colname1,label1, \
1545
1611
  plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
1546
1612
 
1547
1613
  #证券1:先绘制折线图
1548
- import matplotlib.dates as mdate
1549
1614
  date_start=df1.index[0]
1550
1615
  date_end=df1.index[-1]
1551
1616
  if date_range and not date_freq: