siat 3.7.28__py3-none-any.whl → 3.8.10__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
@@ -30,7 +30,8 @@ plt.rcParams['xtick.direction'] = 'inout' # 将x轴的刻度线方向设置向
30
30
  plt.rcParams['ytick.direction'] = 'inout' # 将y轴的刻度方向设置向内内
31
31
 
32
32
  #统一设定绘制的图片大小:数值为英寸,1英寸=100像素
33
- plt.rcParams['figure.figsize']=(12.8,7.2)
33
+ #plt.rcParams['figure.figsize']=(12.8,7.2)
34
+ plt.rcParams['figure.figsize']=(12.8,6.4)
34
35
  plt.rcParams['figure.dpi']=300
35
36
  plt.rcParams['font.size'] = 13
36
37
  plt.rcParams['xtick.labelsize']=11 #横轴字体大小
@@ -124,7 +125,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
124
125
  resample_freq='H',loc='best', \
125
126
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
126
127
  mark_top=True,mark_bottom=True,mark_end=True, \
127
- facecolor='whitesmoke'):
128
+ facecolor='whitesmoke',maxticks=15,translate=False):
128
129
  """
129
130
  功能:绘制折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
130
131
  假定:数据表有索引,且已经按照索引排序
@@ -136,6 +137,8 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
136
137
  注意1:需要日期类型作为df索引
137
138
  注意2:date_freq不为False时,必须设置date_range=True,否则无法完成日期设置!
138
139
  """
140
+ DEBUG=False
141
+
139
142
  import pandas as pd
140
143
 
141
144
  #空值判断
@@ -176,6 +179,10 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
176
179
  lwadjust=linewidth_adjust(df)
177
180
 
178
181
  #if 'filled' not in list(df):
182
+ if translate:
183
+ collabel=lang_auto2(collabel)
184
+
185
+ if DEBUG: print(f"df.index: {df.index}")
179
186
  plt.plot(df.index,df[colname],'-',label=collabel, \
180
187
  linestyle='-',color='blue', linewidth=lwadjust)
181
188
  """
@@ -243,7 +250,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
243
250
  x_end = df_end[colname].idxmin() # 末端值的x坐标
244
251
 
245
252
  #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
246
- y1=str(round(y_end,2)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
253
+ y1=str(round(y_end,1)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
247
254
  plt.annotate(text=' '+y1,
248
255
  xy=(x_end, y_end),
249
256
  xytext=(x_end, y_end),fontsize=annotate_size)
@@ -286,6 +293,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
286
293
  plt.fill_between(df.index,attention_value_area[0],attention_value_area[1],color='lightgray',alpha=0.5)
287
294
 
288
295
  import pandas as pd
296
+ from datetime import datetime; date_format="%Y-%m-%d"
289
297
  if not attention_point=='':
290
298
  if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
291
299
  atp_list=[attention_point]
@@ -304,9 +312,12 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
304
312
 
305
313
  #判断是否日期字符串
306
314
  try:
315
+ #at=datetime.strptime(at, date_format)
307
316
  atpd=pd.to_datetime(at)
308
317
  except:
309
318
  atpd=at
319
+
320
+ if DEBUG: print(f"atpd={atpd}")
310
321
  plt.axvline(x=atpd,ls=":",c=color,linewidth=1.5,label=text_lang("关注点","Attention point ")+str(at))
311
322
 
312
323
  if not attention_point_area=='':
@@ -314,12 +325,18 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
314
325
  apa_list=[]
315
326
  for ap in attention_point_area:
316
327
  try:
328
+ #ap=datetime.strptime(ap, date_format)
317
329
  appd=pd.to_datetime(ap)
318
330
  except:
319
331
  appd=ap
320
332
  apa_list=apa_list+[appd]
321
333
 
322
334
  yaxis_data=plt.ylim()
335
+
336
+ if DEBUG:
337
+ print(f"yaxis_data={yaxis_data}")
338
+ print(f"apa_list[0]={apa_list[0]}")
339
+ print(f"apa_list[1]={apa_list[1]}")
323
340
  plt.fill_betweenx(yaxis_data,apa_list[0],apa_list[1],color='powderblue',alpha=0.5)
324
341
 
325
342
  if average_value:
@@ -352,7 +369,11 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
352
369
  if ylabeltxt != '' or average_value or isinstance(zeroline,bool):
353
370
  if haveLegend:
354
371
  plt.legend(loc=loc,fontsize=legend_txt_size)
355
-
372
+
373
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
374
+ import matplotlib.dates as mdates
375
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
376
+
356
377
  plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
357
378
  try:
358
379
  plt.gca().set_facecolor(facecolor) #设置画布背景颜色
@@ -362,6 +383,11 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
362
383
 
363
384
  if '基金' in titletxt and '收盘价' in ylabeltxt and not ('基金指数' in titletxt):
364
385
  ylabeltxt=ylabeltxt.replace('收盘价','单位净值')
386
+
387
+ if translate:
388
+ ylabeltxt=lang_auto2(ylabeltxt)
389
+ footnote=lang_auto2(footnote)
390
+ titletxt=lang_auto2(titletxt)
365
391
 
366
392
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
367
393
  plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
@@ -396,7 +422,8 @@ def plot_line2(df1,ticker1,colname1,label1, \
396
422
  yline=999,attention_value_area='', \
397
423
  xline=999,attention_point_area='', \
398
424
  resample_freq='H',loc1='best',loc2='best', \
399
- color1='red',color2='blue',facecolor='whitesmoke'):
425
+ color1='red',color2='blue',facecolor='whitesmoke', \
426
+ maxticks=20):
400
427
  """
401
428
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
402
429
  假定:数据表有索引,且已经按照索引排序
@@ -431,7 +458,8 @@ def plot_line2(df1,ticker1,colname1,label1, \
431
458
  xline=xline,attention_point_area=attention_point_area, \
432
459
  resample_freq=resample_freq, \
433
460
  loc1=loc1,loc2=loc2, \
434
- color1=color1,color2=color2,facecolor=facecolor)
461
+ color1=color1,color2=color2,facecolor=facecolor, \
462
+ maxticks=maxticks)
435
463
  else:
436
464
  plot_line2_twinx(df1,ticker1,colname1,label1, \
437
465
  df2,ticker2,colname2,label2, \
@@ -439,7 +467,8 @@ def plot_line2(df1,ticker1,colname1,label1, \
439
467
  resample_freq=resample_freq, \
440
468
  xline=xline,attention_point_area=attention_point_area, \
441
469
  loc1=loc1,loc2=loc2, \
442
- color1=color1,color2=color2,facecolor=facecolor)
470
+ color1=color1,color2=color2,facecolor=facecolor, \
471
+ maxticks=maxticks)
443
472
  return
444
473
 
445
474
 
@@ -453,7 +482,8 @@ def plot2_line2(df1,ticker1,colname1,label1, \
453
482
  xline=999,attention_point_area='', \
454
483
  resample_freq='H',loc1='best',loc2='best', \
455
484
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
456
- color1='red',color2='blue',facecolor='whitesmoke'):
485
+ color1='red',color2='blue',facecolor='whitesmoke', \
486
+ maxticks=20):
457
487
  """
458
488
  注意:可能有bug,twinx=True时左纵坐标轴和横坐标轴标记可能发生重叠!!!暂不建议使用
459
489
  facecolor不起作用
@@ -492,7 +522,8 @@ def plot2_line2(df1,ticker1,colname1,label1, \
492
522
  resample_freq=resample_freq, \
493
523
  loc1=loc1,loc2=loc2, \
494
524
  date_range=date_range,date_freq=date_freq,date_fmt=date_fmt, \
495
- color1=color1,color2=color2,facecolor=facecolor)
525
+ color1=color1,color2=color2,facecolor=facecolor, \
526
+ maxticks=maxticks)
496
527
  else:
497
528
  plot_line2_twinx2(df1,ticker1,colname1,label1, \
498
529
  df2,ticker2,colname2,label2, \
@@ -501,7 +532,9 @@ def plot2_line2(df1,ticker1,colname1,label1, \
501
532
  resample_freq=resample_freq, \
502
533
  loc1=loc1,loc2=loc2, \
503
534
  date_range=date_range,date_freq=date_freq,date_fmt=date_fmt, \
504
- color1=color1,color2=color2,facecolor=facecolor)
535
+ color1=color1,color2=color2,facecolor=facecolor, \
536
+ maxticks=maxticks)
537
+
505
538
  return
506
539
 
507
540
 
@@ -517,7 +550,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
517
550
  resample_freq='H', \
518
551
  loc1='best',loc2='best', \
519
552
  color1='red',color2='blue',facecolor='whitesmoke', \
520
- ticker_type='auto'):
553
+ ticker_type='auto',maxticks=15):
521
554
  """
522
555
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
523
556
  假定:数据表有索引,且已经按照索引排序
@@ -610,6 +643,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
610
643
 
611
644
  #是否绘制垂直线
612
645
  import pandas as pd
646
+ from datetime import datetime; date_format="%Y-%m-%d"
613
647
  if xline != 999:
614
648
  attention_point=xline
615
649
  #用于关注点的颜色列表
@@ -633,6 +667,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
633
667
 
634
668
  #判断是否日期字符串
635
669
  try:
670
+ at=datetime.strptime(at, date_format)
636
671
  atpd=pd.to_datetime(at)
637
672
  except:
638
673
  atpd=at
@@ -647,6 +682,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
647
682
  apa_list=[]
648
683
  for ap in attention_point_area:
649
684
  try:
685
+ ap=datetime.strptime(ap, date_format)
650
686
  appd=pd.to_datetime(ap)
651
687
  except:
652
688
  appd=ap
@@ -721,6 +757,11 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
721
757
 
722
758
  # 同轴绘图时,loc1/loc2未用上!
723
759
  plt.legend(loc=loc1,fontsize=legend_txt_size)
760
+
761
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
762
+ import matplotlib.dates as mdates
763
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
764
+
724
765
  plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
725
766
  try:
726
767
  plt.gca().set_facecolor(facecolor)
@@ -765,7 +806,8 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
765
806
  loc1='best',loc2='best', \
766
807
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
767
808
  color1='red',color2='blue',facecolor='whitesmoke', \
768
- ticker_type='auto'):
809
+ ticker_type='auto', \
810
+ maxticks=15):
769
811
  """
770
812
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
771
813
  假定:数据表有索引,且已经按照索引排序
@@ -869,6 +911,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
869
911
 
870
912
  #是否绘制垂直线
871
913
  import pandas as pd
914
+ from datetime import datetime; date_format="%Y-%m-%d"
872
915
  if xline != 999:
873
916
  attention_point=xline
874
917
  #用于关注点的颜色列表
@@ -891,6 +934,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
891
934
 
892
935
  #判断是否日期字符串
893
936
  try:
937
+ at=datetime.strptime(at, date_format)
894
938
  atpd=pd.to_datetime(at)
895
939
  except:
896
940
  atpd=at
@@ -905,6 +949,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
905
949
  apa_list=[]
906
950
  for ap in attention_point_area:
907
951
  try:
952
+ ap=datetime.strptime(ap, date_format)
908
953
  appd=pd.to_datetime(ap)
909
954
  except:
910
955
  appd=ap
@@ -991,6 +1036,11 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
991
1036
 
992
1037
  # 同轴绘图时,loc1/loc2未用上!
993
1038
  plt.legend(loc=loc1,fontsize=legend_txt_size)
1039
+
1040
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
1041
+ import matplotlib.dates as mdates
1042
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
1043
+
994
1044
  plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
995
1045
  try:
996
1046
  plt.gca().set_facecolor(facecolor)
@@ -1014,7 +1064,8 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
1014
1064
  xline=999,attention_point_area='', \
1015
1065
  loc1='upper left',loc2='lower left', \
1016
1066
  color1='red',color2='blue',facecolor='whitesmoke', \
1017
- ticker_type='auto'):
1067
+ ticker_type='auto', \
1068
+ maxticks=15):
1018
1069
  """
1019
1070
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
1020
1071
  假定:数据表有索引,且已经按照索引排序
@@ -1073,6 +1124,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
1073
1124
 
1074
1125
  #绘制关注点
1075
1126
  import pandas as pd
1127
+ from datetime import datetime; date_format="%Y-%m-%d"
1076
1128
  if xline != 999:
1077
1129
  attention_point=xline
1078
1130
 
@@ -1100,6 +1152,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
1100
1152
 
1101
1153
  #判断是否日期字符串
1102
1154
  try:
1155
+ at=datetime.strptime(at, date_format)
1103
1156
  atpd=pd.to_datetime(at)
1104
1157
  except:
1105
1158
  atpd=at
@@ -1110,6 +1163,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
1110
1163
  apa_list=[]
1111
1164
  for ap in attention_point_area:
1112
1165
  try:
1166
+ ap=datetime.strptime(ap, date_format)
1113
1167
  appd=pd.to_datetime(ap)
1114
1168
  except:
1115
1169
  appd=ap
@@ -1200,6 +1254,11 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
1200
1254
  label2txt=label2+'('+ticker_name(ticker2,ticker_type_list[1])+')'
1201
1255
  ax2.set_ylabel(label2txt,fontsize=ylabel_txt_size)
1202
1256
  ax2.legend(loc=loc2,fontsize=legend_txt_size)
1257
+
1258
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
1259
+ import matplotlib.dates as mdates
1260
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
1261
+ ax2.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
1203
1262
 
1204
1263
  #自动优化x轴标签
1205
1264
  plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
@@ -1233,7 +1292,8 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1233
1292
  resample_freq='H',loc1='upper left',loc2='lower left', \
1234
1293
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
1235
1294
  color1='red',color2='blue',facecolor='whitesmoke', \
1236
- ticker_type='auto'):
1295
+ ticker_type='auto', \
1296
+ maxticks=15):
1237
1297
  """
1238
1298
  功能:绘制两个证券的折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
1239
1299
  假定:数据表有索引,且已经按照索引排序
@@ -1304,6 +1364,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1304
1364
 
1305
1365
  #绘制关注点
1306
1366
  import pandas as pd
1367
+ from datetime import datetime; date_format="%Y-%m-%d"
1307
1368
  if xline != 999:
1308
1369
  attention_point=xline
1309
1370
 
@@ -1331,6 +1392,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1331
1392
 
1332
1393
  #判断是否日期字符串
1333
1394
  try:
1395
+ at=datetime.strptime(at, date_format)
1334
1396
  atpd=pd.to_datetime(at)
1335
1397
  except:
1336
1398
  atpd=at
@@ -1341,6 +1403,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1341
1403
  apa_list=[]
1342
1404
  for ap in attention_point_area:
1343
1405
  try:
1406
+ ap=datetime.strptime(ap, date_format)
1344
1407
  appd=pd.to_datetime(ap)
1345
1408
  except:
1346
1409
  appd=ap
@@ -1445,6 +1508,11 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1445
1508
  label2txt=label2+'('+ticker_name(ticker2,ticker_type_list[1])+')'
1446
1509
  ax2.set_ylabel(label2txt,fontsize=ylabel_txt_size)
1447
1510
  ax2.legend(loc=loc2,fontsize=legend_txt_size)
1511
+
1512
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
1513
+ import matplotlib.dates as mdates
1514
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
1515
+ ax2.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
1448
1516
 
1449
1517
  #自动优化x轴标签
1450
1518
  #格式化时间轴标注
@@ -1478,11 +1546,14 @@ if __name__ =="__main__":
1478
1546
 
1479
1547
  def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1480
1548
  data_label=True,resample_freq='H',smooth=True,linewidth=1.5, \
1481
- loc='best',annotate=False,annotate_value=False,plus_sign=False, \
1549
+ band_area='',loc='best', \
1550
+ annotate=False,annotate_value=False,plus_sign=False, \
1482
1551
  attention_value='',attention_value_area='', \
1483
1552
  attention_point='',attention_point_area='', \
1484
1553
  mark_top=False,mark_bottom=False,mark_end=False, \
1485
- ticker_type='auto',facecolor='whitesmoke'):
1554
+ ticker_type='auto',facecolor='whitesmoke', \
1555
+ maxticks_enable=True,maxticks=15, \
1556
+ translate=False):
1486
1557
  """
1487
1558
  函数功能:根据df的内容绘制折线图
1488
1559
  输入参数:
@@ -1500,6 +1571,10 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1500
1571
  注意:需要日期类型作为df索引
1501
1572
  """
1502
1573
  DEBUG=False
1574
+ if DEBUG:
1575
+ print(f"band_area={band_area}")
1576
+ print(f"df0={df0}")
1577
+
1503
1578
 
1504
1579
  if DEBUG:
1505
1580
  print("annotate=",annotate,"annotate_value=",annotate_value)
@@ -1552,6 +1627,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1552
1627
  firstline=True
1553
1628
 
1554
1629
  #绘制折线图
1630
+ ax=plt.gca()
1555
1631
  print('')
1556
1632
  y_end_list=[]
1557
1633
  for c in collist:
@@ -1598,7 +1674,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1598
1674
  clabel=c+str(round(dfg[c].values[0],2))
1599
1675
  else:
1600
1676
  clabel=c
1601
- plt.plot(dfg,label=clabel,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1677
+ plt.plot(dfg,label=auto_translate2(clabel,translate),linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1602
1678
  else:
1603
1679
  plt.plot(dfg,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1604
1680
 
@@ -1615,12 +1691,12 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1615
1691
  if annotate_value: #在标记曲线名称的同时标记其末端数值
1616
1692
  #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1617
1693
  y1=str(round(y_end,2)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
1618
- plt.annotate(text=c+':'+y1,
1694
+ plt.annotate(text=' '+auto_translate2(c,translate)+': '+y1,
1619
1695
  xy=(x_end, y_end),
1620
1696
  xytext=(x_end, y_end),fontsize=annotate_size,
1621
1697
  color=last_line_color)
1622
1698
  else:
1623
- plt.annotate(text=c,
1699
+ plt.annotate(text=' '+auto_translate2(c,translate),
1624
1700
  xy=(x_end, y_end),
1625
1701
  #xytext=(x_end, y_end),fontsize=9)
1626
1702
  xytext=(x_end, y_end),fontsize=annotate_size,
@@ -1669,7 +1745,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1669
1745
  x_end = df_end[c].idxmin() # 末端值的x坐标
1670
1746
 
1671
1747
  #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1672
- y1=str(round(y_end,2)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
1748
+ y1=str(round(y_end,1)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
1673
1749
  plt.annotate(text=' '+y1,
1674
1750
  xy=(x_end, y_end),
1675
1751
  xytext=(x_end, y_end),fontsize=annotate_size,
@@ -1696,8 +1772,35 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1696
1772
  if not attention_value_area=='':
1697
1773
  if isinstance(attention_value_area,list) and len(attention_value_area)>=2:
1698
1774
  plt.fill_between(dfg.index,attention_value_area[0],attention_value_area[1],color='lightgray',alpha=0.5)
1775
+
1776
+ #绘制曲线之间的带状区域
1777
+ if DEBUG:
1778
+ print(f"dfg={dfg}")
1779
+
1780
+ if band_area != '' and isinstance(band_area,list) and len(band_area)>=2:
1781
+ upper_line=band_area[0]; lower_line=band_area[1]
1782
+ if upper_line not in collist:
1783
+ upper_line=ectranslate(upper_line)
1784
+ lower_line=ectranslate(lower_line)
1699
1785
 
1700
- import pandas as pd
1786
+ if upper_line not in collist:
1787
+ upper_line=ticker_name(upper_line)
1788
+ lower_line=ticker_name(lower_line)
1789
+
1790
+ if upper_line not in collist:
1791
+ upper_line=None
1792
+ lower_line=None
1793
+
1794
+ if not (upper_line is None) and not (lower_line is None):
1795
+ try:
1796
+ plt.fill_between(df2.index,df2[upper_line],df2[lower_line],df2[upper_line] > df2[lower_line],color='aquamarine',alpha=0.5,label='',interpolate=True)
1797
+ plt.fill_between(df2.index,df2[upper_line],df2[lower_line],df2[upper_line] < df2[lower_line],color='lightcoral',alpha=0.5,label='',interpolate=True)
1798
+ except:
1799
+ print(f" #Warning(draw_lines): band area elements {upper_line} or {lower_line} not found")
1800
+
1801
+ import pandas as pd
1802
+ from datetime import datetime; date_format="%Y-%m-%d"
1803
+ from datetime import datetime; date_format="%Y-%m-%d"
1701
1804
  if not attention_point=='':
1702
1805
  if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
1703
1806
  atp_list=[attention_point]
@@ -1721,10 +1824,13 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1721
1824
 
1722
1825
  color=atp_color_list[-1]
1723
1826
 
1724
- #判断是否日期字符串
1725
1827
  try:
1828
+ #判断是否日期字符串
1829
+ at=datetime.strptime(at, date_format)
1830
+ #若是日期字符串
1726
1831
  atpd=pd.to_datetime(at)
1727
1832
  except:
1833
+ #不是日期字符串
1728
1834
  atpd=at
1729
1835
 
1730
1836
  """
@@ -1752,6 +1858,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1752
1858
  apa_list=[]
1753
1859
  for ap in attention_point_area:
1754
1860
  try:
1861
+ ap=datetime.strptime(ap, date_format)
1755
1862
  appd=pd.to_datetime(ap)
1756
1863
  except:
1757
1864
  appd=ap
@@ -1764,19 +1871,28 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1764
1871
  if axhline_label !="":
1765
1872
  if '零线' in axhline_label:
1766
1873
  axhline_label=''
1767
- plt.axhline(y=axhline_value,label=axhline_label,color='black',linestyle=':',linewidth=2)
1874
+
1875
+ max_values = df2.max(numeric_only=True); global_max_values=max_values.max()
1876
+ min_values = df2.min(numeric_only=True); global_min_values=min_values.min()
1877
+ if global_max_values >= axhline_value and global_min_values <= axhline_value:
1878
+ plt.axhline(y=axhline_value,label=auto_translate2(axhline_label,translate),color='black',linestyle=':',linewidth=2)
1768
1879
  #plt.axhline(y=axhline_value,color='purple',linestyle=':',linewidth=1.5)
1769
1880
 
1770
1881
  #坐标轴标记
1771
1882
  y_label_t=ectranslate(y_label)
1772
- plt.ylabel(y_label_t,fontweight='bold',fontsize=ylabel_txt_size)
1883
+ plt.ylabel(auto_translate2(y_label_t,translate),fontweight='bold',fontsize=ylabel_txt_size)
1773
1884
 
1774
1885
  x_label_t=ectranslate(x_label)
1775
1886
  if x_label != "":
1776
- plt.xlabel(x_label_t,fontweight='bold',fontsize=xlabel_txt_size,ha='center')
1887
+ plt.xlabel(auto_translate2(x_label_t,translate),fontweight='bold',fontsize=xlabel_txt_size,ha='center')
1777
1888
  #图示标题
1778
- plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
1889
+ plt.title(auto_translate2(title_txt,translate),fontweight='bold',fontsize=title_txt_size)
1779
1890
 
1891
+ if maxticks_enable:
1892
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
1893
+ import matplotlib.dates as mdates
1894
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
1895
+
1780
1896
  plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
1781
1897
  try:
1782
1898
  plt.gca().set_facecolor(facecolor)
@@ -1822,7 +1938,7 @@ if __name__=='__main__':
1822
1938
 
1823
1939
  #==============================================================================
1824
1940
  def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1825
- data_label=False,resample_freq='6H',smooth=True, \
1941
+ data_label=False,resample_freq='1D',smooth=True, \
1826
1942
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
1827
1943
  colorlist=[],lslist=[],lwlist=[], \
1828
1944
  #指定纵轴两个变量之间的区域
@@ -1835,7 +1951,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1835
1951
  attention_point_area='', \
1836
1952
  annotate=False,annotate_value=False, \
1837
1953
  mark_top=False,mark_bottom=False,mark_end=False, \
1838
- facecolor='whitesmoke'):
1954
+ facecolor='whitesmoke',maxticks=20,translate=False):
1839
1955
  """
1840
1956
  函数功能:根据df的内容绘制折线图
1841
1957
  输入参数:
@@ -1858,6 +1974,9 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1858
1974
  """
1859
1975
  import pandas as pd
1860
1976
  DEBUG=False
1977
+ if DEBUG:
1978
+ print(f"band_area={band_area}")
1979
+ print(f"df0={df0}")
1861
1980
 
1862
1981
  #空值判断
1863
1982
  if len(df0) ==0:
@@ -1927,17 +2046,17 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1927
2046
 
1928
2047
  if (lcolor !='') and (lls !=''):
1929
2048
  if not annotate:
1930
- plt.plot(df[c],label=c,linewidth=llw,ls=lls,color=lcolor)
2049
+ plt.plot(df[c],label=auto_translate2(c,translate),linewidth=llw,ls=lls,color=lcolor)
1931
2050
  else:
1932
2051
  plt.plot(df[c],linewidth=llw,ls=lls,color=lcolor)
1933
2052
  elif (lcolor !=''):
1934
2053
  if not annotate:
1935
- plt.plot(df[c],label=c,linewidth=llw,color=lcolor)
2054
+ plt.plot(df[c],label=auto_translate2(c,translate),linewidth=llw,color=lcolor)
1936
2055
  else:
1937
2056
  plt.plot(df[c],linewidth=llw,color=lcolor)
1938
2057
  else:
1939
2058
  if not annotate:
1940
- plt.plot(df[c],label=c,linewidth=llw)
2059
+ plt.plot(df[c],label=auto_translate2(c,translate),linewidth=llw)
1941
2060
  else:
1942
2061
  plt.plot(df[c],linewidth=llw)
1943
2062
 
@@ -1987,12 +2106,12 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1987
2106
  if annotate_value: #在标记曲线名称的同时标记其末端数值
1988
2107
  #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1989
2108
  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,4))
1990
- plt.annotate(text=c+':'+y1,
2109
+ plt.annotate(text=auto_translate2(c,translate)+': '+y1,
1991
2110
  xy=(x_end, y_end),
1992
2111
  xytext=(x_end, y_end),fontsize=annotate_size,
1993
2112
  color=last_line_color)
1994
2113
  else:
1995
- plt.annotate(text=c,
2114
+ plt.annotate(text=auto_translate2(c,translate),
1996
2115
  xy=(x_end, y_end),
1997
2116
  xytext=(x_end, y_end),fontsize=annotate_size,
1998
2117
  color=last_line_color)
@@ -2004,7 +2123,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2004
2123
  x_end = df_end[c].idxmin() # 末端值的x坐标
2005
2124
 
2006
2125
  #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
2007
- y1=str(round(y_end,2)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
2126
+ y1=str(round(y_end,1)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
2008
2127
  plt.annotate(text=y1,
2009
2128
  xy=(x_end, y_end),
2010
2129
  xytext=(x_end, y_end),fontsize=annotate_size,
@@ -2026,15 +2145,19 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2026
2145
  lower_line=None
2027
2146
 
2028
2147
  if not (upper_line is None) and not (lower_line is None):
2029
- """
2030
- plt.fill_between(df.index,df[upper_line],df[lower_line],color='moccasin',alpha=0.5,label='',where=df[upper_line]>=df[lower_line])
2031
- plt.fill_between(df.index,df[upper_line],df[lower_line],color='aquamarine',alpha=0.5,label='',where=df[upper_line]<=df[lower_line])
2032
- """
2033
- #plt.fill_between(df.index,df[upper_line],df[lower_line],color='aquamarine',alpha=0.5,label='')
2034
- plt.fill_between(df.index,df[upper_line],df[lower_line],df[upper_line] > df[lower_line],color='aquamarine',alpha=0.5,label='',interpolate=True)
2035
- plt.fill_between(df.index,df[upper_line],df[lower_line],df[upper_line] < df[lower_line],color='lightcoral',alpha=0.5,label='',interpolate=True)
2036
- #plt.fill_between(df.index,df[upper_line],df[lower_line],df[upper_line] == df[lower_line],color='lightgray',alpha=0.5,label='')
2037
-
2148
+ try:
2149
+ """
2150
+ plt.fill_between(df.index,df[upper_line],df[lower_line],color='moccasin',alpha=0.5,label='',where=df[upper_line]>=df[lower_line])
2151
+ plt.fill_between(df.index,df[upper_line],df[lower_line],color='aquamarine',alpha=0.5,label='',where=df[upper_line]<=df[lower_line])
2152
+ """
2153
+ #plt.fill_between(df.index,df[upper_line],df[lower_line],color='aquamarine',alpha=0.5,label='')
2154
+ plt.fill_between(df.index,df[upper_line],df[lower_line],df[upper_line] > df[lower_line],color='aquamarine',alpha=0.5,label='',interpolate=True)
2155
+ plt.fill_between(df.index,df[upper_line],df[lower_line],df[upper_line] < df[lower_line],color='lightcoral',alpha=0.5,label='',interpolate=True)
2156
+ #plt.fill_between(df.index,df[upper_line],df[lower_line],df[upper_line] == df[lower_line],color='lightgray',alpha=0.5,label='')
2157
+ except:
2158
+ print(f" #Warning(draw_lines2): lack of data for either {upper_line} or {lower_line}")
2159
+ #return None
2160
+
2038
2161
  #绘制水平辅助线
2039
2162
  if axhline_label !="":
2040
2163
  if DEBUG:
@@ -2068,6 +2191,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2068
2191
  plt.fill_between(df.index,attention_value_area[0],attention_value_area[1],color='lightgray',alpha=0.5)
2069
2192
 
2070
2193
  import pandas as pd
2194
+ from datetime import datetime; date_format="%Y-%m-%d"
2071
2195
  if not attention_point=='':
2072
2196
  if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
2073
2197
  atp_list=[attention_point]
@@ -2085,6 +2209,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2085
2209
 
2086
2210
  #判断是否日期字符串
2087
2211
  try:
2212
+ at=datetime.strptime(at, date_format)
2088
2213
  atpd=pd.to_datetime(at)
2089
2214
  except:
2090
2215
  atpd=at
@@ -2095,6 +2220,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2095
2220
  apa_list=[]
2096
2221
  for ap in attention_point_area:
2097
2222
  try:
2223
+ ap=datetime.strptime(ap, date_format)
2098
2224
  appd=pd.to_datetime(ap)
2099
2225
  except:
2100
2226
  appd=ap
@@ -2104,11 +2230,16 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2104
2230
  plt.fill_betweenx(yaxis_data,apa_list[0],apa_list[1],color='powderblue',alpha=0.5)
2105
2231
 
2106
2232
  #坐标轴标记
2107
- plt.ylabel(y_label,fontweight='bold',fontsize=ylabel_txt_size)
2233
+ plt.ylabel(auto_translate2(y_label,translate),fontweight='bold',fontsize=ylabel_txt_size)
2108
2234
  if x_label != "":
2109
- plt.xlabel(x_label,fontweight='bold',fontsize=xlabel_txt_size,ha='center')
2235
+ plt.xlabel(auto_translate2(x_label,translate),fontweight='bold',fontsize=xlabel_txt_size,ha='center')
2110
2236
  #图示标题
2111
- plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
2237
+ plt.title(auto_translate2(title_txt,translate),fontweight='bold',fontsize=title_txt_size)
2238
+
2239
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
2240
+ import matplotlib.dates as mdates
2241
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
2242
+
2112
2243
  plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
2113
2244
  try:
2114
2245
  plt.gca().set_facecolor(facecolor)
@@ -2266,7 +2397,8 @@ def plot_2lines(df01,colname1,label1, \
2266
2397
  df02,colname2,label2, \
2267
2398
  ylabeltxt,titletxt,footnote,hline=0,vline=0,resample_freq='H', \
2268
2399
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
2269
- facecolor='whitesmoke'):
2400
+ facecolor='whitesmoke', \
2401
+ maxticks=15):
2270
2402
  """
2271
2403
  功能:绘制两个证券的折线图。如果hline=0不绘制水平虚线,vline=0不绘制垂直虚线
2272
2404
  假定:数据表有日期索引,且已经按照索引排序
@@ -2356,6 +2488,10 @@ def plot_2lines(df01,colname1,label1, \
2356
2488
  plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
2357
2489
  plt.legend(loc='best',fontsize=legend_txt_size)
2358
2490
 
2491
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
2492
+ import matplotlib.dates as mdates
2493
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
2494
+
2359
2495
  plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
2360
2496
  try:
2361
2497
  plt.gca().set_facecolor(facecolor)
@@ -2624,7 +2760,7 @@ if __name__=='__main__':
2624
2760
  firstColSpecial=True
2625
2761
  colWidth=0.1
2626
2762
  tabScale=2
2627
- figsize=(10,6)
2763
+ figsize=(12.8,6.4)
2628
2764
  cellLoc='right'
2629
2765
  fontsize=10
2630
2766
 
@@ -2636,7 +2772,7 @@ if __name__=='__main__':
2636
2772
  pandas2plttable(df)
2637
2773
 
2638
2774
  def pandas2plttable(df,titletxt,firstColSpecial=True,colWidth=0.1,tabScale=2,cellLoc='right', \
2639
- figsize=(10,4),fontsize=13,auto_len=False,title_x=0.5):
2775
+ figsize=(12.8,6.4),fontsize=13,auto_len=False,title_x=0.5):
2640
2776
  """
2641
2777
  功能:将一个df转换为matplotlib表格格式,打印图形表格,适应性广
2642
2778
  firstColSpecial:第一列是否特殊处理,默认True
@@ -2688,7 +2824,6 @@ def pandas2plttable(df,titletxt,firstColSpecial=True,colWidth=0.1,tabScale=2,cel
2688
2824
  for i in range(0,len(df)):
2689
2825
  vals=vals+[list(df.iloc[i])]
2690
2826
 
2691
- #plt.figure(figsize=figsize,dpi=figdpi)
2692
2827
  plt.figure(figsize=figsize)
2693
2828
 
2694
2829
  if not auto_len: