siat 3.7.29__py3-none-any.whl → 3.8.2__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
@@ -124,7 +124,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
124
124
  resample_freq='H',loc='best', \
125
125
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
126
126
  mark_top=True,mark_bottom=True,mark_end=True, \
127
- facecolor='whitesmoke'):
127
+ facecolor='whitesmoke',maxticks=10,translate=False):
128
128
  """
129
129
  功能:绘制折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
130
130
  假定:数据表有索引,且已经按照索引排序
@@ -136,6 +136,8 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
136
136
  注意1:需要日期类型作为df索引
137
137
  注意2:date_freq不为False时,必须设置date_range=True,否则无法完成日期设置!
138
138
  """
139
+ DEBUG=False
140
+
139
141
  import pandas as pd
140
142
 
141
143
  #空值判断
@@ -176,6 +178,10 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
176
178
  lwadjust=linewidth_adjust(df)
177
179
 
178
180
  #if 'filled' not in list(df):
181
+ if translate:
182
+ collabel=lang_auto2(collabel)
183
+
184
+ if DEBUG: print(f"df.index: {df.index}")
179
185
  plt.plot(df.index,df[colname],'-',label=collabel, \
180
186
  linestyle='-',color='blue', linewidth=lwadjust)
181
187
  """
@@ -243,7 +249,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
243
249
  x_end = df_end[colname].idxmin() # 末端值的x坐标
244
250
 
245
251
  #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))
252
+ 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
253
  plt.annotate(text=' '+y1,
248
254
  xy=(x_end, y_end),
249
255
  xytext=(x_end, y_end),fontsize=annotate_size)
@@ -286,6 +292,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
286
292
  plt.fill_between(df.index,attention_value_area[0],attention_value_area[1],color='lightgray',alpha=0.5)
287
293
 
288
294
  import pandas as pd
295
+ from datetime import datetime; date_format="%Y-%m-%d"
289
296
  if not attention_point=='':
290
297
  if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
291
298
  atp_list=[attention_point]
@@ -304,9 +311,12 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
304
311
 
305
312
  #判断是否日期字符串
306
313
  try:
314
+ #at=datetime.strptime(at, date_format)
307
315
  atpd=pd.to_datetime(at)
308
316
  except:
309
317
  atpd=at
318
+
319
+ if DEBUG: print(f"atpd={atpd}")
310
320
  plt.axvline(x=atpd,ls=":",c=color,linewidth=1.5,label=text_lang("关注点","Attention point ")+str(at))
311
321
 
312
322
  if not attention_point_area=='':
@@ -314,12 +324,18 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
314
324
  apa_list=[]
315
325
  for ap in attention_point_area:
316
326
  try:
327
+ #ap=datetime.strptime(ap, date_format)
317
328
  appd=pd.to_datetime(ap)
318
329
  except:
319
330
  appd=ap
320
331
  apa_list=apa_list+[appd]
321
332
 
322
333
  yaxis_data=plt.ylim()
334
+
335
+ if DEBUG:
336
+ print(f"yaxis_data={yaxis_data}")
337
+ print(f"apa_list[0]={apa_list[0]}")
338
+ print(f"apa_list[1]={apa_list[1]}")
323
339
  plt.fill_betweenx(yaxis_data,apa_list[0],apa_list[1],color='powderblue',alpha=0.5)
324
340
 
325
341
  if average_value:
@@ -352,7 +368,11 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
352
368
  if ylabeltxt != '' or average_value or isinstance(zeroline,bool):
353
369
  if haveLegend:
354
370
  plt.legend(loc=loc,fontsize=legend_txt_size)
355
-
371
+
372
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
373
+ import matplotlib.dates as mdates
374
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
375
+
356
376
  plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
357
377
  try:
358
378
  plt.gca().set_facecolor(facecolor) #设置画布背景颜色
@@ -362,6 +382,11 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
362
382
 
363
383
  if '基金' in titletxt and '收盘价' in ylabeltxt and not ('基金指数' in titletxt):
364
384
  ylabeltxt=ylabeltxt.replace('收盘价','单位净值')
385
+
386
+ if translate:
387
+ ylabeltxt=lang_auto2(ylabeltxt)
388
+ footnote=lang_auto2(footnote)
389
+ titletxt=lang_auto2(titletxt)
365
390
 
366
391
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
367
392
  plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
@@ -610,6 +635,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
610
635
 
611
636
  #是否绘制垂直线
612
637
  import pandas as pd
638
+ from datetime import datetime; date_format="%Y-%m-%d"
613
639
  if xline != 999:
614
640
  attention_point=xline
615
641
  #用于关注点的颜色列表
@@ -633,6 +659,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
633
659
 
634
660
  #判断是否日期字符串
635
661
  try:
662
+ at=datetime.strptime(at, date_format)
636
663
  atpd=pd.to_datetime(at)
637
664
  except:
638
665
  atpd=at
@@ -647,6 +674,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
647
674
  apa_list=[]
648
675
  for ap in attention_point_area:
649
676
  try:
677
+ ap=datetime.strptime(ap, date_format)
650
678
  appd=pd.to_datetime(ap)
651
679
  except:
652
680
  appd=ap
@@ -869,6 +897,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
869
897
 
870
898
  #是否绘制垂直线
871
899
  import pandas as pd
900
+ from datetime import datetime; date_format="%Y-%m-%d"
872
901
  if xline != 999:
873
902
  attention_point=xline
874
903
  #用于关注点的颜色列表
@@ -891,6 +920,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
891
920
 
892
921
  #判断是否日期字符串
893
922
  try:
923
+ at=datetime.strptime(at, date_format)
894
924
  atpd=pd.to_datetime(at)
895
925
  except:
896
926
  atpd=at
@@ -905,6 +935,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
905
935
  apa_list=[]
906
936
  for ap in attention_point_area:
907
937
  try:
938
+ ap=datetime.strptime(ap, date_format)
908
939
  appd=pd.to_datetime(ap)
909
940
  except:
910
941
  appd=ap
@@ -1073,6 +1104,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
1073
1104
 
1074
1105
  #绘制关注点
1075
1106
  import pandas as pd
1107
+ from datetime import datetime; date_format="%Y-%m-%d"
1076
1108
  if xline != 999:
1077
1109
  attention_point=xline
1078
1110
 
@@ -1100,6 +1132,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
1100
1132
 
1101
1133
  #判断是否日期字符串
1102
1134
  try:
1135
+ at=datetime.strptime(at, date_format)
1103
1136
  atpd=pd.to_datetime(at)
1104
1137
  except:
1105
1138
  atpd=at
@@ -1110,6 +1143,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
1110
1143
  apa_list=[]
1111
1144
  for ap in attention_point_area:
1112
1145
  try:
1146
+ ap=datetime.strptime(ap, date_format)
1113
1147
  appd=pd.to_datetime(ap)
1114
1148
  except:
1115
1149
  appd=ap
@@ -1304,6 +1338,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1304
1338
 
1305
1339
  #绘制关注点
1306
1340
  import pandas as pd
1341
+ from datetime import datetime; date_format="%Y-%m-%d"
1307
1342
  if xline != 999:
1308
1343
  attention_point=xline
1309
1344
 
@@ -1331,6 +1366,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1331
1366
 
1332
1367
  #判断是否日期字符串
1333
1368
  try:
1369
+ at=datetime.strptime(at, date_format)
1334
1370
  atpd=pd.to_datetime(at)
1335
1371
  except:
1336
1372
  atpd=at
@@ -1341,6 +1377,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1341
1377
  apa_list=[]
1342
1378
  for ap in attention_point_area:
1343
1379
  try:
1380
+ ap=datetime.strptime(ap, date_format)
1344
1381
  appd=pd.to_datetime(ap)
1345
1382
  except:
1346
1383
  appd=ap
@@ -1478,11 +1515,12 @@ if __name__ =="__main__":
1478
1515
 
1479
1516
  def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1480
1517
  data_label=True,resample_freq='H',smooth=True,linewidth=1.5, \
1481
- loc='best',annotate=False,annotate_value=False,plus_sign=False, \
1518
+ band_area='',loc='best', \
1519
+ annotate=False,annotate_value=False,plus_sign=False, \
1482
1520
  attention_value='',attention_value_area='', \
1483
1521
  attention_point='',attention_point_area='', \
1484
1522
  mark_top=False,mark_bottom=False,mark_end=False, \
1485
- ticker_type='auto',facecolor='whitesmoke'):
1523
+ ticker_type='auto',facecolor='whitesmoke',maxticks=10,translate=False):
1486
1524
  """
1487
1525
  函数功能:根据df的内容绘制折线图
1488
1526
  输入参数:
@@ -1500,6 +1538,10 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1500
1538
  注意:需要日期类型作为df索引
1501
1539
  """
1502
1540
  DEBUG=False
1541
+ if DEBUG:
1542
+ print(f"band_area={band_area}")
1543
+ print(f"df0={df0}")
1544
+
1503
1545
 
1504
1546
  if DEBUG:
1505
1547
  print("annotate=",annotate,"annotate_value=",annotate_value)
@@ -1552,6 +1594,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1552
1594
  firstline=True
1553
1595
 
1554
1596
  #绘制折线图
1597
+ ax=plt.gca()
1555
1598
  print('')
1556
1599
  y_end_list=[]
1557
1600
  for c in collist:
@@ -1598,7 +1641,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1598
1641
  clabel=c+str(round(dfg[c].values[0],2))
1599
1642
  else:
1600
1643
  clabel=c
1601
- plt.plot(dfg,label=clabel,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1644
+ plt.plot(dfg,label=auto_translate2(clabel,translate),linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1602
1645
  else:
1603
1646
  plt.plot(dfg,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
1604
1647
 
@@ -1615,12 +1658,12 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1615
1658
  if annotate_value: #在标记曲线名称的同时标记其末端数值
1616
1659
  #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1617
1660
  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,
1661
+ plt.annotate(text=' '+auto_translate2(c,translate)+':'+y1,
1619
1662
  xy=(x_end, y_end),
1620
1663
  xytext=(x_end, y_end),fontsize=annotate_size,
1621
1664
  color=last_line_color)
1622
1665
  else:
1623
- plt.annotate(text=c,
1666
+ plt.annotate(text=' '+auto_translate2(c,translate),
1624
1667
  xy=(x_end, y_end),
1625
1668
  #xytext=(x_end, y_end),fontsize=9)
1626
1669
  xytext=(x_end, y_end),fontsize=annotate_size,
@@ -1669,7 +1712,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1669
1712
  x_end = df_end[c].idxmin() # 末端值的x坐标
1670
1713
 
1671
1714
  #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))
1715
+ 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
1716
  plt.annotate(text=' '+y1,
1674
1717
  xy=(x_end, y_end),
1675
1718
  xytext=(x_end, y_end),fontsize=annotate_size,
@@ -1696,8 +1739,35 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1696
1739
  if not attention_value_area=='':
1697
1740
  if isinstance(attention_value_area,list) and len(attention_value_area)>=2:
1698
1741
  plt.fill_between(dfg.index,attention_value_area[0],attention_value_area[1],color='lightgray',alpha=0.5)
1742
+
1743
+ #绘制曲线之间的带状区域
1744
+ if DEBUG:
1745
+ print(f"dfg={dfg}")
1746
+
1747
+ if band_area != '' and isinstance(band_area,list) and len(band_area)>=2:
1748
+ upper_line=band_area[0]; lower_line=band_area[1]
1749
+ if upper_line not in collist:
1750
+ upper_line=ectranslate(upper_line)
1751
+ lower_line=ectranslate(lower_line)
1699
1752
 
1700
- import pandas as pd
1753
+ if upper_line not in collist:
1754
+ upper_line=ticker_name(upper_line)
1755
+ lower_line=ticker_name(lower_line)
1756
+
1757
+ if upper_line not in collist:
1758
+ upper_line=None
1759
+ lower_line=None
1760
+
1761
+ if not (upper_line is None) and not (lower_line is None):
1762
+ try:
1763
+ 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)
1764
+ 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)
1765
+ except:
1766
+ print(f" #Warning(draw_lines): band area elements {upper_line} or {lower_line} not found")
1767
+
1768
+ import pandas as pd
1769
+ from datetime import datetime; date_format="%Y-%m-%d"
1770
+ from datetime import datetime; date_format="%Y-%m-%d"
1701
1771
  if not attention_point=='':
1702
1772
  if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
1703
1773
  atp_list=[attention_point]
@@ -1721,10 +1791,13 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1721
1791
 
1722
1792
  color=atp_color_list[-1]
1723
1793
 
1724
- #判断是否日期字符串
1725
1794
  try:
1795
+ #判断是否日期字符串
1796
+ at=datetime.strptime(at, date_format)
1797
+ #若是日期字符串
1726
1798
  atpd=pd.to_datetime(at)
1727
1799
  except:
1800
+ #不是日期字符串
1728
1801
  atpd=at
1729
1802
 
1730
1803
  """
@@ -1752,6 +1825,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1752
1825
  apa_list=[]
1753
1826
  for ap in attention_point_area:
1754
1827
  try:
1828
+ ap=datetime.strptime(ap, date_format)
1755
1829
  appd=pd.to_datetime(ap)
1756
1830
  except:
1757
1831
  appd=ap
@@ -1764,19 +1838,23 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1764
1838
  if axhline_label !="":
1765
1839
  if '零线' in axhline_label:
1766
1840
  axhline_label=''
1767
- plt.axhline(y=axhline_value,label=axhline_label,color='black',linestyle=':',linewidth=2)
1841
+ plt.axhline(y=axhline_value,label=auto_translate2(axhline_label,translate),color='black',linestyle=':',linewidth=2)
1768
1842
  #plt.axhline(y=axhline_value,color='purple',linestyle=':',linewidth=1.5)
1769
1843
 
1770
1844
  #坐标轴标记
1771
1845
  y_label_t=ectranslate(y_label)
1772
- plt.ylabel(y_label_t,fontweight='bold',fontsize=ylabel_txt_size)
1846
+ plt.ylabel(auto_translate2(y_label_t,translate),fontweight='bold',fontsize=ylabel_txt_size)
1773
1847
 
1774
1848
  x_label_t=ectranslate(x_label)
1775
1849
  if x_label != "":
1776
- plt.xlabel(x_label_t,fontweight='bold',fontsize=xlabel_txt_size,ha='center')
1850
+ plt.xlabel(auto_translate2(x_label_t,translate),fontweight='bold',fontsize=xlabel_txt_size,ha='center')
1777
1851
  #图示标题
1778
- plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
1852
+ plt.title(auto_translate2(title_txt,translate),fontweight='bold',fontsize=title_txt_size)
1779
1853
 
1854
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
1855
+ import matplotlib.dates as mdates
1856
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
1857
+
1780
1858
  plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
1781
1859
  try:
1782
1860
  plt.gca().set_facecolor(facecolor)
@@ -1822,7 +1900,7 @@ if __name__=='__main__':
1822
1900
 
1823
1901
  #==============================================================================
1824
1902
  def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1825
- data_label=False,resample_freq='6H',smooth=True, \
1903
+ data_label=False,resample_freq='1D',smooth=True, \
1826
1904
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
1827
1905
  colorlist=[],lslist=[],lwlist=[], \
1828
1906
  #指定纵轴两个变量之间的区域
@@ -1835,7 +1913,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1835
1913
  attention_point_area='', \
1836
1914
  annotate=False,annotate_value=False, \
1837
1915
  mark_top=False,mark_bottom=False,mark_end=False, \
1838
- facecolor='whitesmoke'):
1916
+ facecolor='whitesmoke',maxticks=10,translate=False):
1839
1917
  """
1840
1918
  函数功能:根据df的内容绘制折线图
1841
1919
  输入参数:
@@ -1858,6 +1936,9 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1858
1936
  """
1859
1937
  import pandas as pd
1860
1938
  DEBUG=False
1939
+ if DEBUG:
1940
+ print(f"band_area={band_area}")
1941
+ print(f"df0={df0}")
1861
1942
 
1862
1943
  #空值判断
1863
1944
  if len(df0) ==0:
@@ -1927,17 +2008,17 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1927
2008
 
1928
2009
  if (lcolor !='') and (lls !=''):
1929
2010
  if not annotate:
1930
- plt.plot(df[c],label=c,linewidth=llw,ls=lls,color=lcolor)
2011
+ plt.plot(df[c],label=auto_translate2(c,translate),linewidth=llw,ls=lls,color=lcolor)
1931
2012
  else:
1932
2013
  plt.plot(df[c],linewidth=llw,ls=lls,color=lcolor)
1933
2014
  elif (lcolor !=''):
1934
2015
  if not annotate:
1935
- plt.plot(df[c],label=c,linewidth=llw,color=lcolor)
2016
+ plt.plot(df[c],label=auto_translate2(c,translate),linewidth=llw,color=lcolor)
1936
2017
  else:
1937
2018
  plt.plot(df[c],linewidth=llw,color=lcolor)
1938
2019
  else:
1939
2020
  if not annotate:
1940
- plt.plot(df[c],label=c,linewidth=llw)
2021
+ plt.plot(df[c],label=auto_translate2(c,translate),linewidth=llw)
1941
2022
  else:
1942
2023
  plt.plot(df[c],linewidth=llw)
1943
2024
 
@@ -1987,12 +2068,12 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1987
2068
  if annotate_value: #在标记曲线名称的同时标记其末端数值
1988
2069
  #y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
1989
2070
  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,
2071
+ plt.annotate(text=auto_translate2(c,translate)+':'+y1,
1991
2072
  xy=(x_end, y_end),
1992
2073
  xytext=(x_end, y_end),fontsize=annotate_size,
1993
2074
  color=last_line_color)
1994
2075
  else:
1995
- plt.annotate(text=c,
2076
+ plt.annotate(text=auto_translate2(c,translate),
1996
2077
  xy=(x_end, y_end),
1997
2078
  xytext=(x_end, y_end),fontsize=annotate_size,
1998
2079
  color=last_line_color)
@@ -2004,7 +2085,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2004
2085
  x_end = df_end[c].idxmin() # 末端值的x坐标
2005
2086
 
2006
2087
  #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))
2088
+ 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
2089
  plt.annotate(text=y1,
2009
2090
  xy=(x_end, y_end),
2010
2091
  xytext=(x_end, y_end),fontsize=annotate_size,
@@ -2026,15 +2107,19 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2026
2107
  lower_line=None
2027
2108
 
2028
2109
  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
-
2110
+ try:
2111
+ """
2112
+ plt.fill_between(df.index,df[upper_line],df[lower_line],color='moccasin',alpha=0.5,label='',where=df[upper_line]>=df[lower_line])
2113
+ plt.fill_between(df.index,df[upper_line],df[lower_line],color='aquamarine',alpha=0.5,label='',where=df[upper_line]<=df[lower_line])
2114
+ """
2115
+ #plt.fill_between(df.index,df[upper_line],df[lower_line],color='aquamarine',alpha=0.5,label='')
2116
+ 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)
2117
+ 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)
2118
+ #plt.fill_between(df.index,df[upper_line],df[lower_line],df[upper_line] == df[lower_line],color='lightgray',alpha=0.5,label='')
2119
+ except:
2120
+ print(f" #Warning(draw_lines2): lack of data for either {upper_line} or {lower_line}")
2121
+ #return None
2122
+
2038
2123
  #绘制水平辅助线
2039
2124
  if axhline_label !="":
2040
2125
  if DEBUG:
@@ -2068,6 +2153,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2068
2153
  plt.fill_between(df.index,attention_value_area[0],attention_value_area[1],color='lightgray',alpha=0.5)
2069
2154
 
2070
2155
  import pandas as pd
2156
+ from datetime import datetime; date_format="%Y-%m-%d"
2071
2157
  if not attention_point=='':
2072
2158
  if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
2073
2159
  atp_list=[attention_point]
@@ -2085,6 +2171,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2085
2171
 
2086
2172
  #判断是否日期字符串
2087
2173
  try:
2174
+ at=datetime.strptime(at, date_format)
2088
2175
  atpd=pd.to_datetime(at)
2089
2176
  except:
2090
2177
  atpd=at
@@ -2095,6 +2182,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2095
2182
  apa_list=[]
2096
2183
  for ap in attention_point_area:
2097
2184
  try:
2185
+ ap=datetime.strptime(ap, date_format)
2098
2186
  appd=pd.to_datetime(ap)
2099
2187
  except:
2100
2188
  appd=ap
@@ -2104,11 +2192,16 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2104
2192
  plt.fill_betweenx(yaxis_data,apa_list[0],apa_list[1],color='powderblue',alpha=0.5)
2105
2193
 
2106
2194
  #坐标轴标记
2107
- plt.ylabel(y_label,fontweight='bold',fontsize=ylabel_txt_size)
2195
+ plt.ylabel(auto_translate2(y_label,translate),fontweight='bold',fontsize=ylabel_txt_size)
2108
2196
  if x_label != "":
2109
- plt.xlabel(x_label,fontweight='bold',fontsize=xlabel_txt_size,ha='center')
2197
+ plt.xlabel(auto_translate2(x_label,translate),fontweight='bold',fontsize=xlabel_txt_size,ha='center')
2110
2198
  #图示标题
2111
- plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
2199
+ plt.title(auto_translate2(title_txt,translate),fontweight='bold',fontsize=title_txt_size)
2200
+
2201
+ # 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
2202
+ import matplotlib.dates as mdates
2203
+ ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
2204
+
2112
2205
  plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
2113
2206
  try:
2114
2207
  plt.gca().set_facecolor(facecolor)
siat/sector_china.py CHANGED
@@ -889,9 +889,17 @@ def display_industry_sw(sw_level='1',numberPerLine=4,colalign='left'):
889
889
  """
890
890
  按照类别打印申万行业列表,名称(代码),每行5个, 套壳函数
891
891
  """
892
- itype_list=['1','2','3','F','S','B','C']
893
- sw_level_list=['1','2','3','F','S','B','C']
894
- pos=sw_level_list.index(sw_level)
892
+ #itype_list=['1','2','3','F','S','B','C']
893
+ itype_list=['1','2','3','F','S','B']
894
+ #sw_level_list=['1','2','3','F','S','B','C']
895
+ sw_level_list=['1','2','3','F','S','B']
896
+
897
+ try:
898
+ pos=sw_level_list.index(sw_level)
899
+ except:
900
+ print(f" #Warning(display_industry_sw): no such level in Shenwan system {sw_level}")
901
+ print(f" Supported Shenwan system: {sw_level_list}")
902
+
895
903
  itype=itype_list[pos]
896
904
 
897
905
  print_industry_sw(itype=itype,numberPerLine=numberPerLine,colalign=colalign)
@@ -2884,6 +2892,7 @@ if __name__=='__main__':
2884
2892
 
2885
2893
  def find_peers_china(industry='',top=20,rank=20,sw_level='2'):
2886
2894
  """
2895
+ ===========================================================================
2887
2896
  功能:找出一个申万行业的上市公司排名
2888
2897
  主要参数:
2889
2898
  industry:申万行业名称。当industry = '',显示的内容由sw_level控制。申万二级行业分类
@@ -3489,10 +3498,13 @@ if __name__=='__main__':
3489
3498
 
3490
3499
  def find_industry_sw(ticker,level='1',ticker_order=True,max_sleep=30):
3491
3500
  """
3501
+ ===========================================================================
3492
3502
  功能:寻找一只或一组股票所属的申万行业,支持股票代码和股票名称。
3493
- level='1':默认只查找申万1级行业,以便节省时间
3494
- ticker_order=True:默认输出结果按照ticker中的顺序,而非按照所属行业排序
3495
- max_sleep:为防止反爬虫,默认每次爬虫后睡眠最多几秒钟
3503
+ level='1':默认只查找申万1级行业;查找2/3级行业时间较久,可能触发反爬虫机制。
3504
+ ticker_order=True:默认输出结果按照ticker中的顺序,而非按照所属行业排序。
3505
+ max_sleep:为防止触发反爬虫机制,默认每次爬虫后睡眠最多30秒钟。
3506
+
3507
+ 返回值:查找结果df。
3496
3508
  """
3497
3509
  print(" Searching shenwan industries for securities ... ...")
3498
3510
 
@@ -3621,21 +3633,24 @@ if __name__=='__main__':
3621
3633
 
3622
3634
  peers=stock_industry_peer_em(ticker,indicator="市盈率",rank=10)
3623
3635
 
3624
- def stock_peers_em(ticker='',indicator='',rank=10, \
3636
+ def stock_peers_em(ticker='',indicator='市盈率',rank=10, \
3625
3637
  force_show_stock=True, \
3626
3638
  font_size="16px",facecolor="papayawhip", \
3627
3639
  numberPerLine=5):
3628
3640
  """
3629
- 功能:基于东方财富行业分类,查找股票所属的行业板块以及主要同行排名
3630
- 特点:行业分类较粗糙,略胜于无
3641
+ ===========================================================================
3642
+ 功能:基于东方财富行业分类,查找股票所属的行业板块以及主要同行排名。
3643
+ 特点:行业分类较粗糙,略胜于无。
3631
3644
  主要参数:
3632
- ticker:股票代码,默认''显示所有板块名称
3633
- indicator:排名指标,默认''。例如:"股价"、"流动性"、"市净率"、"市盈率"
3634
- rank:排名数量,默认10前十名
3635
- force_show_stock:是否显示股票信息,默认False
3636
- font_size:表格字体大小,默认"16px"
3637
- facecolor:输出表格的背景颜色,默认"papayawhip",
3638
- numberPerLine:输出表格中的每行显示个数,默认5
3645
+ ticker:股票代码,默认''显示所有板块名称。
3646
+ indicator:排名指标,默认''。例如:"股价"、"流动性"、"市净率"、"市盈率"
3647
+ rank:排名数量,默认10前十名。
3648
+ force_show_stock:是否显示股票信息,默认False
3649
+ font_size:表格字体大小,默认"16px"
3650
+ facecolor:输出表格的背景颜色,默认"papayawhip"
3651
+ numberPerLine:输出表格中的每行显示个数,默认5
3652
+
3653
+ 注意:若结果异常,可尝试升级插件akshare。
3639
3654
 
3640
3655
  示例:
3641
3656
  industries=stock_peers_em() # 显示东方财富所有行业板块分类
@@ -3663,6 +3678,7 @@ def stock_peers_em(ticker='',indicator='',rank=10, \
3663
3678
  except:
3664
3679
  if not ticker=='':
3665
3680
  print(" #Warning(stock_peer_em): stock info not found for",ticker)
3681
+ print(" Solution: if stock code is correct, upgrade akshare and try again")
3666
3682
 
3667
3683
  df_em=ak.stock_board_industry_name_em()
3668
3684
  #df_em.sort_values(by="板块名称",ascending=True,inplace=True)
@@ -3725,7 +3741,8 @@ def stock_peers_em(ticker='',indicator='',rank=10, \
3725
3741
  df_disp=cfg[collist].tail(abs(rank))
3726
3742
 
3727
3743
  #强制显示所选股票
3728
- if force_show_stock and rank != 10:
3744
+ #if force_show_stock and rank != 10:
3745
+ if force_show_stock:
3729
3746
  #所选股票是否在其中?
3730
3747
  if not ticker[:6] in list(df_disp["代码"]):
3731
3748
  ticker_seq=cfg[cfg["代码"]==ticker[:6]]["序号"].values[0]
@@ -3780,8 +3797,22 @@ def concept_stocks_em(concept='',ticker='',indicator="市盈率",rank=10, \
3780
3797
  force_show_stock=False, \
3781
3798
  font_size="16px",facecolor="papayawhip",numberPerLine=5):
3782
3799
  """
3783
- 功能:基于东方财富概念板块,查找关键字相关概念以及股票业绩
3784
- 特点:概念板块划分细致,同一股票可能分属多个板块,与行业分类不同
3800
+ ===========================================================================
3801
+ 功能:基于东方财富概念板块,查找关键字相关概念以及股票业绩。
3802
+ 特点:概念板块划分细致,同一股票可能分属多个板块,与行业分类不同。
3803
+ 参数:
3804
+ concept:概念板块名称,或名称中的关键字,默认''输出所有概念板块名称;
3805
+ 若查找到多个名称,则优先输出查找到的名称;
3806
+ 若仅仅找到一个板块,则按indicator输出该板块的股票排行。
3807
+ ticker:股票代码,默认''
3808
+ indicator:指标名称,默认"市盈率",还支持:股价,市净率,涨跌幅,流动性,换手率。
3809
+ rank:排名,支持正负数,默认10。
3810
+ force_show_stock:若ticker不为空,且不在rank范围内,是否强制显示该股票,默认False。
3811
+ font_size:显示字体大小,默认"16px"。
3812
+ facecolor:表格背景颜色,默认"papayawhip"。
3813
+ numberPerLine:当显示板块名称时,每行显示个数,默认5。
3814
+
3815
+ 返回值:df
3785
3816
  """
3786
3817
  if indicator in ["股价","股票价格","价格","收盘价","价位"]:
3787
3818
  indicator="最新价"
siat/stock.py CHANGED
@@ -987,7 +987,7 @@ def security_mindicators(ticker,measures,
987
987
  titletxt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker,ticker_type=ticker_type)
988
988
 
989
989
  draw_lines2(df,y_label,x_label,axhline_value,axhline_label,titletxt, \
990
- data_label=False,resample_freq='6H',smooth=smooth, \
990
+ data_label=False,resample_freq='1D',smooth=smooth, \
991
991
  date_range=date_range,date_freq=date_freq,date_fmt='%Y-%m-%d', \
992
992
  attention_value=attention_value,attention_value_area=attention_value_area, \
993
993
  attention_point=attention_point,attention_point_area=attention_point_area, \