siat 2.14.2__py3-none-any.whl → 3.0.1__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=1,mark_bottom=1,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,18 +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
- av=str(round(av,2)) if av < 100 else str(int(av))
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))
214
239
  #footnote=footnote + ",均值"+av
215
240
  footnote="注:期间均值"+av+";"+footnote
216
241
 
217
242
  #绘制趋势线
218
243
  #print("--Debug(plot_line): power=",power)
219
244
  if power > 0:
220
- lang=check_language()
221
- trend_txt='趋势线'
222
- #trend_txt=''
223
- if lang == 'English':
224
- trend_txt='Trend line'
245
+ trend_txt=text_lang('趋势线','Trend line')
246
+
225
247
  try:
226
248
  #生成行号,借此将横轴的日期数量化,以便拟合
227
249
  df['id']=range(len(df))
@@ -233,13 +255,16 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
233
255
  plt.plot(df.index, f(df.id),"r--", label=trend_txt,linewidth=1)
234
256
  haveLegend=True
235
257
  except:
236
- 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.")
237
259
 
238
260
  if ylabeltxt != '' or average_value or isinstance(zeroline,bool):
239
261
  if haveLegend:
240
262
  plt.legend(loc=loc,fontsize=legend_txt_size)
241
263
 
242
264
  plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
265
+
266
+ if '基金' in titletxt and '收盘价' in ylabeltxt:
267
+ ylabeltxt=ylabeltxt.replace('收盘价','单位净值')
243
268
 
244
269
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
245
270
  plt.xlabel(footnote,fontsize=xlabel_txt_size)
@@ -250,8 +275,6 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
250
275
 
251
276
  return
252
277
 
253
- if __name__ =="__main__":
254
- plot_line(df,'Close',"收盘价","价格","万科股票","数据来源:新浪/stooq",power=4)
255
278
 
256
279
  #==============================================================================
257
280
  if __name__ =="__main__":
@@ -366,11 +389,12 @@ def plot2_line2(df1,ticker1,colname1,label1, \
366
389
 
367
390
  def plot_line2_coaxial(df01,ticker1,colname1,label1, \
368
391
  df02,ticker2,colname2,label2, \
369
- ylabeltxt,titletxt,footnote, \
370
- power=0,datatag1=False,datatag2=False,zeroline=False, \
371
- yline=999,xline=999,resample_freq='H', \
372
- loc1='best',loc2='best', \
373
- 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'):
374
398
  """
375
399
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
376
400
  假定:数据表有索引,且已经按照索引排序
@@ -394,19 +418,24 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
394
418
  df2=df_smooth_manual(df02x,resample_freq=resample_freq)
395
419
  except:
396
420
  df2=df02
421
+
422
+ #预处理ticker_type
423
+ ticker_type_list=ticker_type_preprocess_mticker_mixed([ticker1,ticker2],ticker_type)
424
+
397
425
  #证券1:先绘制折线图
398
426
 
399
427
  if ticker1 == '':
400
428
  label1txt=label1
401
429
  else:
402
430
  if label1 == '':
403
- label1txt=codetranslate(ticker1)
431
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
404
432
  else:
405
- label1txt=codetranslate(ticker1)+'('+label1+')'
433
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+'('+label1+')'
406
434
 
407
435
  lwadjust=linewidth_adjust(df1)
408
436
  plt.plot(df1.index,df1[colname1],'-',label=label1txt, \
409
437
  linestyle='-',linewidth=lwadjust,color=color1)
438
+
410
439
  #证券1:绘制数据标签
411
440
  if datatag1:
412
441
  for x, y in zip(df1.index, df1[colname1]):
@@ -426,10 +455,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
426
455
 
427
456
  #绘证券1:制趋势线
428
457
  if power > 0:
429
- lang=check_language()
430
- trend_txt='趋势线'
431
- if lang == 'English':
432
- trend_txt='Trend line'
458
+ trend_txt=text_lang('趋势线','Trend line')
433
459
 
434
460
  try:
435
461
  #生成行号,借此将横轴的日期数量化,以便拟合
@@ -443,7 +469,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
443
469
  if ticker1 == '':
444
470
  label1txt=''
445
471
  else:
446
- label1txt=codetranslate(ticker1)+"("+trend_txt+")"
472
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
447
473
 
448
474
  #plt.plot(df1.index, f(df1.id),"g--", label=label1txt,linewidth=1)
449
475
  plt.plot(df1.index, f(df1.id),"g--", label='',linewidth=1)
@@ -454,9 +480,9 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
454
480
  label2txt=label2
455
481
  else:
456
482
  if label2 == '':
457
- label2txt=codetranslate(ticker2)
483
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
458
484
  else:
459
- label2txt=codetranslate(ticker2)+'('+label2+')'
485
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+'('+label2+')'
460
486
 
461
487
  lwadjust=linewidth_adjust(df2)
462
488
  plt.plot(df2.index,df2[colname2],'-',label=label2txt, \
@@ -485,7 +511,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
485
511
  if ticker2 == '':
486
512
  label2txt=''
487
513
  else:
488
- label2txt=codetranslate(ticker2)+"("+trend_txt+")"
514
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
489
515
 
490
516
  #plt.plot(df2.index, f(df2.id),"r--", label=label2txt,linewidth=1)
491
517
  plt.plot(df2.index, f(df2.id),"r--", label='',linewidth=1)
@@ -529,7 +555,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
529
555
  yline=999,xline=999,resample_freq='H', \
530
556
  loc1='best',loc2='best', \
531
557
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
532
- color1='red',color2='blue'):
558
+ color1='red',color2='blue',ticker_type='auto'):
533
559
  """
534
560
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
535
561
  假定:数据表有索引,且已经按照索引排序
@@ -553,17 +579,19 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
553
579
  df2=df_smooth_manual(df02x,resample_freq=resample_freq)
554
580
  except:
555
581
  df2=df02
582
+
583
+ #预处理ticker_type
584
+ ticker_type_list=ticker_type_preprocess_mticker_mixed([ticker1,ticker2],ticker_type)
585
+
556
586
  #证券1:先绘制折线图
557
-
558
587
  if ticker1 == '':
559
588
  label1txt=label1
560
589
  else:
561
590
  if label1 == '':
562
- label1txt=codetranslate(ticker1)
591
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
563
592
  else:
564
- label1txt=codetranslate(ticker1)+'('+label1+')'
593
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+'('+label1+')'
565
594
 
566
- import matplotlib.dates as mdate
567
595
  ax=plt.gca()
568
596
  date_start=df1.index[0]
569
597
  date_end=df1.index[-1]
@@ -616,7 +644,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
616
644
  if ticker1 == '':
617
645
  label1txt=''
618
646
  else:
619
- label1txt=codetranslate(ticker1)+"("+trend_txt+")"
647
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
620
648
  plt.plot(df1.index, f(df1.id),"g--", label=label1txt,linewidth=1)
621
649
  except: pass
622
650
 
@@ -625,9 +653,9 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
625
653
  label2txt=label2
626
654
  else:
627
655
  if label2 == '':
628
- label2txt=codetranslate(ticker2)
656
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
629
657
  else:
630
- label2txt=codetranslate(ticker2)+'('+label2+')'
658
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+'('+label2+')'
631
659
 
632
660
  date_start=df2.index[0]
633
661
  date_end=df2.index[-1]
@@ -668,7 +696,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
668
696
  if ticker2 == '':
669
697
  label2txt=''
670
698
  else:
671
- label2txt=codetranslate(ticker2)+"("+trend_txt+")"
699
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
672
700
  plt.plot(df2.index, f(df2.id),"r--", label=label2txt,linewidth=1)
673
701
  except: pass
674
702
 
@@ -689,7 +717,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
689
717
  df02,ticker2,colname2,label2, \
690
718
  titletxt,footnote,power=0,datatag1=False,datatag2=False, \
691
719
  resample_freq='H',loc1='upper left',loc2='lower left', \
692
- color1='red',color2='blue'):
720
+ color1='red',color2='blue',ticker_type='auto'):
693
721
  """
694
722
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
695
723
  假定:数据表有索引,且已经按照索引排序
@@ -714,9 +742,11 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
714
742
  df2=df_smooth_manual(df02x,resample_freq=resample_freq)
715
743
  except:
716
744
  df2=df02
717
-
745
+
746
+ #预处理ticker_type
747
+ ticker_type_list=ticker_type_preprocess_mticker_mixed([ticker1,ticker2],ticker_type)
748
+
718
749
  #证券1:绘制折线图,双坐标轴
719
- import matplotlib.dates as mdates
720
750
  fig = plt.figure()
721
751
  ax = fig.add_subplot(111)
722
752
 
@@ -724,9 +754,9 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
724
754
  label1txt=label1
725
755
  else:
726
756
  if label1 == '':
727
- label1txt=codetranslate(ticker1)
757
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
728
758
  else:
729
- label1txt=codetranslate(ticker1)+'('+label1+')'
759
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+'('+label1+')'
730
760
 
731
761
  lwadjust=linewidth_adjust(df1)
732
762
  ax.plot(df1.index,df1[colname1],'-',label=label1txt, \
@@ -754,7 +784,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
754
784
  if ticker1 == '':
755
785
  label1txt=''
756
786
  else:
757
- label1txt=codetranslate(ticker1)+"("+trend_txt+")"
787
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
758
788
  ax.plot(df1.index, f(df1.id),"r--", label=label1txt,linewidth=1)
759
789
 
760
790
  #绘证券2:建立第二y轴
@@ -764,9 +794,9 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
764
794
  label2txt=label2
765
795
  else:
766
796
  if label2 == '':
767
- label2txt=codetranslate(ticker2)
797
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
768
798
  else:
769
- label2txt=codetranslate(ticker2)+'('+label2+')'
799
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+'('+label2+')'
770
800
 
771
801
  lwadjust=linewidth_adjust(df2)
772
802
  ax2.plot(df2.index,df2[colname2],'-',label=label2txt, \
@@ -794,7 +824,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
794
824
  if ticker2 == '':
795
825
  label2txt=''
796
826
  else:
797
- label2txt=codetranslate(ticker2)+"("+trend_txt+")"
827
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
798
828
  ax2.plot(df2.index, f(df2.id),"c--", label=label2txt,linewidth=1)
799
829
 
800
830
  ax.set_xlabel(footnote,fontsize=xlabel_txt_size)
@@ -803,9 +833,9 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
803
833
  label1txt=label1
804
834
  else:
805
835
  if label1 == "":
806
- label1txt=codetranslate(ticker1)
836
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
807
837
  else:
808
- label1txt=label1+'('+codetranslate(ticker1)+')'
838
+ label1txt=label1+'('+ticker_name(ticker1,ticker_type_list[0])+')'
809
839
  ax.set_ylabel(label1txt,fontsize=ylabel_txt_size)
810
840
  ax.legend(loc=loc1,fontsize=legend_txt_size)
811
841
 
@@ -813,9 +843,9 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
813
843
  label2txt=label2
814
844
  else:
815
845
  if label2 == "":
816
- label2txt=codetranslate(ticker2)
846
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
817
847
  else:
818
- label2txt=label2+'('+codetranslate(ticker2)+')'
848
+ label2txt=label2+'('+ticker_name(ticker2,ticker_type_list[1])+')'
819
849
  ax2.set_ylabel(label2txt,fontsize=ylabel_txt_size)
820
850
  ax2.legend(loc=loc2,fontsize=legend_txt_size)
821
851
 
@@ -849,7 +879,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
849
879
  titletxt,footnote,power=0,datatag1=False,datatag2=False, \
850
880
  resample_freq='H',loc1='upper left',loc2='lower left', \
851
881
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
852
- color1='red',color2='blue'):
882
+ color1='red',color2='blue',ticker_type='auto'):
853
883
  """
854
884
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
855
885
  假定:数据表有索引,且已经按照索引排序
@@ -874,9 +904,11 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
874
904
  df2=df_smooth_manual(df02x,resample_freq=resample_freq)
875
905
  except:
876
906
  df2=df02
907
+
908
+ #预处理ticker_type
909
+ ticker_type_list=ticker_type_preprocess_mticker_mixed([ticker1,ticker2],ticker_type)
877
910
 
878
911
  #证券1:绘制折线图,双坐标轴
879
- import matplotlib.dates as mdate
880
912
  fig = plt.figure()
881
913
  ax = fig.add_subplot(111)
882
914
 
@@ -884,9 +916,9 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
884
916
  label1txt=label1
885
917
  else:
886
918
  if label1 == '':
887
- label1txt=codetranslate(ticker1)
919
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
888
920
  else:
889
- label1txt=codetranslate(ticker1)+'('+label1+')'
921
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+'('+label1+')'
890
922
 
891
923
  date_start=df1.index[0]
892
924
  date_end=df1.index[-1]
@@ -926,7 +958,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
926
958
  if ticker1 == '':
927
959
  label1txt=''
928
960
  else:
929
- label1txt=codetranslate(ticker1)+"("+trend_txt+")"
961
+ label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
930
962
  ax.plot(df1.index, f(df1.id),"r--", label=label1txt,linewidth=1)
931
963
 
932
964
  #绘证券2:建立第二y轴
@@ -936,9 +968,9 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
936
968
  label2txt=label2
937
969
  else:
938
970
  if label2 == '':
939
- label2txt=codetranslate(ticker2)
971
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
940
972
  else:
941
- label2txt=codetranslate(ticker2)+'('+label2+')'
973
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+'('+label2+')'
942
974
 
943
975
  date_start=df2.index[0]
944
976
  date_end=df2.index[-1]
@@ -978,7 +1010,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
978
1010
  if ticker2 == '':
979
1011
  label2txt=''
980
1012
  else:
981
- label2txt=codetranslate(ticker2)+"("+trend_txt+")"
1013
+ label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
982
1014
 
983
1015
  ax2.plot(df2.index, f(df2.id),"c--", label=label2txt,linewidth=1)
984
1016
 
@@ -988,9 +1020,9 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
988
1020
  label1txt=label1
989
1021
  else:
990
1022
  if label1 == "":
991
- label1txt=codetranslate(ticker1)
1023
+ label1txt=ticker_name(ticker1,ticker_type_list[0])
992
1024
  else:
993
- label1txt=label1+'('+codetranslate(ticker1)+')'
1025
+ label1txt=label1+'('+ticker_name(ticker1,ticker_type_list[0])+')'
994
1026
  ax.set_ylabel(label1txt,fontsize=ylabel_txt_size)
995
1027
  ax.legend(loc=loc1,fontsize=legend_txt_size)
996
1028
 
@@ -998,9 +1030,9 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
998
1030
  label2txt=label2
999
1031
  else:
1000
1032
  if label2 == "":
1001
- label2txt=codetranslate(ticker2)
1033
+ label2txt=ticker_name(ticker2,ticker_type_list[1])
1002
1034
  else:
1003
- label2txt=label2+'('+codetranslate(ticker2)+')'
1035
+ label2txt=label2+'('+ticker_name(ticker2,ticker_type_list[1])+')'
1004
1036
  ax2.set_ylabel(label2txt,fontsize=ylabel_txt_size)
1005
1037
  ax2.legend(loc=loc2,fontsize=legend_txt_size)
1006
1038
 
@@ -1018,7 +1050,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1018
1050
  def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1019
1051
  data_label=True,resample_freq='H',smooth=True,linewidth=1.5, \
1020
1052
  loc='best',annotate=False,annotate_value=False,plus_sign=False, \
1021
- mark_top=0,mark_bottom=0,mark_end=False):
1053
+ mark_top=False,mark_bottom=False,mark_end=False,ticker_type='auto'):
1022
1054
  """
1023
1055
  函数功能:根据df的内容绘制折线图
1024
1056
  输入参数:
@@ -1105,63 +1137,80 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1105
1137
 
1106
1138
  #plt.plot(dfg,label=c,linewidth=linewidth,ls=lsc,marker=mkc,markersize=3)
1107
1139
  lwadjust=linewidth_adjust(dfg)
1140
+
1141
+ """
1108
1142
  if not annotate:
1109
- """
1110
- 注意:许多传入的df字段名已经不是证券代码,此处调用codetranslate将会导致
1111
- 股票名称字典重新下载,耗费时间,且出现黄条。
1112
- 建议:在调用draw_lines之前,先调用codetranslate,将证券代码翻译为证券名称。
1113
- 本函数仅负责绘图,不负责翻译证券名称。
1114
- """
1143
+
1144
+ #注意:许多传入的df字段名已经不是证券代码,此处调用codetranslate将会导致
1145
+ #股票名称字典重新下载,耗费时间,且出现黄条。
1146
+ #建议:在调用draw_lines之前,先调用codetranslate,将证券代码翻译为证券名称。
1147
+ #本函数仅负责绘图,不负责翻译证券名称。
1148
+
1115
1149
  #plt.plot(dfg,label=codetranslate(c),linewidth=linewidth,ls=lsc,marker=mkc,markersize=3)
1116
1150
  plt.plot(dfg,label=c,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1117
1151
  else:
1118
1152
  #plt.plot(dfg[c],label=codetranslate(c),linewidth=linewidth,ls=lsc,marker=mkc,markersize=3)
1119
1153
  #plt.plot(dfg,label=codetranslate(c),linewidth=linewidth,ls=lsc,marker=mkc,markersize=3)
1120
1154
  plt.plot(dfg,label=c,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1121
-
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:
1122
1161
  df_end=dfg.tail(1)
1123
1162
  # df_end[c]必须为数值类型,否则可能出错
1124
1163
  y_end = df_end[c].min() # 末端的y坐标
1125
1164
  x_end = df_end[c].idxmin() # 末端值的x坐标
1126
1165
 
1127
1166
  if annotate_value: #在标记曲线名称的同时标记其末端数值
1128
- 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))
1129
1169
  plt.annotate(text=c+':'+y1,
1130
- xy=(x_end, y_end),
1131
- 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)
1132
1173
  else:
1133
1174
  plt.annotate(text=c,
1134
- xy=(x_end, y_end),
1135
- #xytext=(x_end, y_end),fontsize=9)
1136
- 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)
1137
1179
 
1138
1180
  #plt.plot(df[c],label=c,linewidth=1.5,marker=mkc,markersize=3)
1139
1181
  #为折线加数据标签
1140
1182
  if data_label==True:
1183
+ mark_top=False; mark_bottom=False; mark_end=False
1141
1184
  for a,b in zip(dfg.index,df2[c]):
1142
1185
  plt.text(a,b+0.02,str(round(b,2)), \
1143
1186
  ha='center',va='bottom',fontsize=7)
1144
1187
 
1145
1188
  #标记最高点/最低点
1146
- if mark_top > 0 or mark_bottom > 0:
1189
+ if mark_top or mark_bottom:
1147
1190
  df_mark=dfg[[c]].copy() #避免影响原df
1148
1191
  df_mark.dropna(inplace=True)
1149
1192
  df_mark.sort_values(by=c,ascending=False,inplace=True)
1150
1193
 
1151
- if mark_top > 0:
1152
- df_mark_top=df_mark[:mark_top]
1194
+ if mark_top:
1195
+ df_mark_top=df_mark[:1]
1153
1196
  for x, y in zip(df_mark_top.index, df_mark_top[c]):
1154
- y1=round(y+high_low*0.01,2)
1155
- s='%.0f' if y >= 100 else '%.2f'
1156
- 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)
1157
1203
  plt.scatter(x,y, color='red',marker='8',s=70)
1158
1204
 
1159
- if mark_bottom > 0:
1160
- df_mark_bottom=df_mark[-mark_bottom:]
1205
+ if mark_bottom:
1206
+ df_mark_bottom=df_mark[-1:]
1161
1207
  for x, y in zip(df_mark_bottom.index, df_mark_bottom[c]):
1162
- y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
1163
- s='%.0f' if y >= 100 else '%.2f'
1164
- 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)
1165
1214
  plt.scatter(x,y, color='seagreen',marker='8',s=70)
1166
1215
 
1167
1216
  #标记曲线末端数值
@@ -1170,10 +1219,12 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1170
1219
  y_end = df_end[c].min() # 末端的y坐标
1171
1220
  x_end = df_end[c].idxmin() # 末端值的x坐标
1172
1221
 
1173
- 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))
1174
1224
  plt.annotate(text=' '+y1,
1175
1225
  xy=(x_end, y_end),
1176
- xytext=(x_end, y_end),fontsize=annotate_size)
1226
+ xytext=(x_end, y_end),fontsize=annotate_size,
1227
+ color=last_line_color)
1177
1228
 
1178
1229
 
1179
1230
  #绘制水平辅助线
@@ -1220,7 +1271,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1220
1271
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
1221
1272
  colorlist=[],lslist=[],lwlist=[], \
1222
1273
  band_area='',loc='best',annotate=False,annotate_value=False, \
1223
- mark_top=0,mark_bottom=0,mark_end=False):
1274
+ mark_top=False,mark_bottom=False,mark_end=False):
1224
1275
  """
1225
1276
  函数功能:根据df的内容绘制折线图
1226
1277
  输入参数:
@@ -1268,7 +1319,6 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1268
1319
  high_low=dfmax - dfmin
1269
1320
 
1270
1321
  #定义横轴标签:显示完整开始、结束日期
1271
- import matplotlib.dates as mdate
1272
1322
  ax=plt.gca()
1273
1323
  date_start=df.index[0]
1274
1324
  date_end=df.index[-1]
@@ -1296,35 +1346,44 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1296
1346
  except:
1297
1347
  lwadjust=linewidth_adjust(df)
1298
1348
  plt.plot(df[c],label=c,linewidth=lwadjust)
1349
+ lines = plt.gca().lines; last_line_color = lines[-1].get_color()
1299
1350
  else:
1300
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()
1301
1353
 
1302
1354
  #为折线加数据标签
1303
1355
  if data_label==True:
1356
+ mark_top=False; mark_bottom=False; mark_end=False
1304
1357
  for a,b in zip(df.index,df[c]):
1305
1358
  plt.text(a,b+0.02,str(round(b,2)), \
1306
1359
  ha='center',va='bottom',fontsize=7)
1307
1360
 
1308
1361
  #标记最高点/最低点
1309
- if mark_top > 0 or mark_bottom > 0:
1362
+ if mark_top or mark_bottom:
1310
1363
  df_mark=df[[c]].copy() #避免影响原df
1311
1364
  df_mark.dropna(inplace=True)
1312
1365
  df_mark.sort_values(by=c,ascending=False,inplace=True)
1313
1366
 
1314
- if mark_top > 0:
1315
- df_mark_top=df_mark[:mark_top]
1367
+ if mark_top:
1368
+ df_mark_top=df_mark[:1]
1316
1369
  for x, y in zip(df_mark_top.index, df_mark_top[c]):
1317
- y1=round(y+high_low*0.01,2)
1318
- s='%.0f' if y >= 100 else '%.2f'
1319
- 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)
1320
1376
  plt.scatter(x,y, color='red',marker='8',s=70)
1321
1377
 
1322
- if mark_bottom > 0:
1323
- df_mark_bottom=df_mark[-mark_bottom:]
1378
+ if mark_bottom:
1379
+ df_mark_bottom=df_mark[-1:]
1324
1380
  for x, y in zip(df_mark_bottom.index, df_mark_bottom[c]):
1325
- y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
1326
- s='%.0f' if y >= 100 else '%.2f'
1327
- 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)
1328
1387
  plt.scatter(x,y, color='seagreen',marker='8',s=70)
1329
1388
 
1330
1389
  #曲线末端标记:不建议用于布林带
@@ -1334,14 +1393,17 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1334
1393
  x_end = df_end[c].idxmin() # 末端值的x坐标
1335
1394
 
1336
1395
  if annotate_value: #在标记曲线名称的同时标记其末端数值
1337
- 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))
1338
1398
  plt.annotate(text=c+':'+y1,
1339
1399
  xy=(x_end, y_end),
1340
- xytext=(x_end, y_end),fontsize=annotate_size)
1400
+ xytext=(x_end, y_end),fontsize=annotate_size,
1401
+ color=last_line_color)
1341
1402
  else:
1342
1403
  plt.annotate(text=c,
1343
1404
  xy=(x_end, y_end),
1344
- xytext=(x_end, y_end),fontsize=annotate_size)
1405
+ xytext=(x_end, y_end),fontsize=annotate_size,
1406
+ color=last_line_color)
1345
1407
 
1346
1408
  #处理布林带的mark_end,仅标记上中下线
1347
1409
  if mark_end & (c in collist3):
@@ -1349,10 +1411,12 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1349
1411
  y_end = df_end[c].min() # 末端的y坐标
1350
1412
  x_end = df_end[c].idxmin() # 末端值的x坐标
1351
1413
 
1352
- 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))
1353
1416
  plt.annotate(text=y1,
1354
1417
  xy=(x_end, y_end),
1355
- xytext=(x_end, y_end),fontsize=annotate_size)
1418
+ xytext=(x_end, y_end),fontsize=annotate_size,
1419
+ color=last_line_color)
1356
1420
 
1357
1421
  #绘制带状区域
1358
1422
  if band_area != '' and isinstance(band_area,list) and len(band_area)>=2:
@@ -1547,7 +1611,6 @@ def plot_2lines(df01,colname1,label1, \
1547
1611
  plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
1548
1612
 
1549
1613
  #证券1:先绘制折线图
1550
- import matplotlib.dates as mdate
1551
1614
  date_start=df1.index[0]
1552
1615
  date_end=df1.index[-1]
1553
1616
  if date_range and not date_freq: