我的悬停注释为什么显示 NaN 而不是我的数值?

huangapple go评论89阅读模式
英文:

Why do my hover annotations have NaN instead of my values?

问题

代码部分不需要翻译。以下是您提供的代码的翻译部分:

  1. import yfinance as yf
  2. import mplfinance as mpf
  3. import matplotlib.pyplot as plt
  4. import matplotlib.patches as mpatches
  5. import pandas as pd
  6. import numpy as np
  7. # 获取股票数据的日期范围
  8. start_date = "2020-01-01"
  9. end_date = "2023-06-15"
  10. # 获取特斯拉股票数据
  11. tesla_data = yf.download("TSLA", start=start_date, end=end_date)
  12. tesla_weekly_data = tesla_data.resample("W").agg({"Open": "first", "High": "max", "Low": "min", "Close": "last", "Volume": "sum"}).dropna()
  13. # 获取最新的收盘价
  14. latest_price = tesla_weekly_data['Close'][-1]
  15. # 创建额外的图表
  16. close_price = tesla_weekly_data['Close']
  17. apd = mpf.make_addplot(close_price, color='cyan', width=2)
  18. # 绘制蜡烛图
  19. fig, axes = mpf.plot(tesla_weekly_data,
  20. type='candle',
  21. addplot=apd,
  22. style='yahoo',
  23. title='特斯拉股票价格',
  24. ylabel='价格',
  25. xlabel='日期',
  26. volume=True,
  27. ylabel_lower='成交量',
  28. volume_panel=1,
  29. figsize=(16, 8),
  30. returnfig=True
  31. )
  32. # 将y轴标签移到左侧
  33. axes[0].yaxis.tick_left()
  34. axes[1].yaxis.tick_left()
  35. # 调整价格y轴标签的位置
  36. axes[0].yaxis.set_label_coords(-0.08, 0.5)
  37. # 调整成交量y轴标签的位置
  38. axes[1].yaxis.set_label_coords(-0.08, 0.5)
  39. # 设置价格和成交量的y轴标签
  40. axes[0].set_ylabel('价格', rotation=0, labelpad=20)
  41. axes[1].set_ylabel('成交量', rotation=0, labelpad=20)
  42. # 创建图例框
  43. handles = axes[0].get_legend_handles_labels()[0]
  44. red_patch = mpatches.Patch(color='red')
  45. green_patch = mpatches.Patch(color='green')
  46. cyan_patch = mpatches.Patch(color='cyan')
  47. handles = handles[:2] + [red_patch, green_patch, cyan_patch]
  48. labels = ["涨价", "跌价", "收盘价"]
  49. axes[0].legend(handles=handles, labels=labels)
  50. # 添加一个框以显示当前价格
  51. latest_price_text = f"当前价格: ${latest_price:.2f}"
  52. box_props = dict(boxstyle='round', facecolor='white', edgecolor='black', alpha=0.8)
  53. axes[0].text(0.02, 0.95, latest_price_text, transform=axes[0].transAxes, fontsize=12, verticalalignment='top', bbox=box_props)
  54. # 定义悬停标签格式
  55. hover_label_format = [
  56. ("开盘价: ", lambda x: f"${x:.2f}"),
  57. ("最高价: ", lambda x: f"${x:.2f}"),
  58. ("最低价: ", lambda x: f"${x:.2f}"),
  59. ("收盘价: ", lambda x: f"${x:.2f}"),
  60. ("成交量: ", lambda x: f"{int(x):,}"),
  61. ]
  62. # 创建悬停注释的函数
  63. def hover_annotations(data):
  64. annot = pd.DataFrame(index=data.index, columns=data.columns)
  65. annot_visible = False
  66. texts = []
  67. def onmove(event):
  68. nonlocal annot_visible
  69. if event.inaxes == axes[0]:
  70. index = int(event.xdata)
  71. if index >= len(data.index):
  72. return
  73. values = data.iloc[index]
  74. for label, formatter in hover_label_format:
  75. value = values[label.rstrip(': ')]
  76. if np.isnan(value):
  77. annot.iloc[index][label.rstrip(': ')] = ""
  78. else:
  79. annot.iloc[index][label.rstrip(': ')] = f"{label}{formatter(value)}"
  80. annot_visible = True
  81. else:
  82. annot_visible = False
  83. for t, text, (x, y) in zip(texts, annot.values, zip([event.xdata] or [], [event.ydata] or [])):
  84. if isinstance(x, (list, np.ndarray)):
  85. x = x[0] if len(x) > 0 and not np.isnan(x[0]) else None
  86. if isinstance(y, (list, np.ndarray)):
  87. y = y[0] if len(y) > 0 and not np.isnan(y[0]) else None
  88. if x is not None and y is not None:
  89. t.set_position((x, y))
  90. t.set_text('\n'.join(map(str, text)))
  91. t.set_visible(annot_visible)
  92. fig.canvas.draw_idle()
  93. for _ in data.index:
  94. t = axes[0].text(0, 0, '', visible=False, ha='left', va='top')
  95. texts.append(t)
  96. fig.canvas.mpl_connect('motion_notify_event', onmove)
  97. return annot
  98. # 将悬停注释附加到图表
  99. annotations = hover_annotations(tesla_weekly_data)
  100. # 显示图表
  101. plt.show()

如果您运行此代码,它将绘制特斯拉股票的蜡烛图,并提供悬停功能,以显示开盘价、最高价、最低价、收盘价和成交量的信息。

英文:
  1. import yfinance as yf
  2. import mplfinance as mpf
  3. import matplotlib.pyplot as plt
  4. import matplotlib.patches as mpatches
  5. import pandas as pd
  6. import numpy as np
  7. # Dates to get stock data
  8. start_date = "2020-01-01"
  9. end_date = "2023-06-15"
  10. # Fetch Tesla stock data
  11. tesla_data = yf.download("TSLA", start=start_date, end=end_date)
  12. tesla_weekly_data = tesla_data.resample("W").agg({"Open": "first", "High": "max", "Low": "min", "Close": "last", "Volume": "sum"}).dropna()
  13. # Get the latest closing price
  14. latest_price = tesla_weekly_data['Close'][-1]
  15. # Create additional plot
  16. close_price = tesla_weekly_data['Close']
  17. apd = mpf.make_addplot(close_price, color='cyan', width=2)
  18. # Plot the candlestick chart
  19. fig, axes = mpf.plot(tesla_weekly_data,
  20. type='candle',
  21. addplot=apd,
  22. style='yahoo',
  23. title='Tesla Stock Prices',
  24. ylabel='Price',
  25. xlabel='Date',
  26. volume=True,
  27. ylabel_lower='Volume',
  28. volume_panel=1,
  29. figsize=(16, 8),
  30. returnfig=True
  31. )
  32. # Move the y-axis labels to the left side
  33. axes[0].yaxis.tick_left()
  34. axes[1].yaxis.tick_left()
  35. # Adjust the position of the y-axis label for price
  36. axes[0].yaxis.set_label_coords(-0.08, 0.5)
  37. # Adjust the position of the y-axis label for volume
  38. axes[1].yaxis.set_label_coords(-0.08, 0.5)
  39. # Set y-axis label for price and volume
  40. axes[0].set_ylabel('Price', rotation=0, labelpad=20)
  41. axes[1].set_ylabel('Volume', rotation=0, labelpad=20)
  42. # Make the legend box
  43. handles = axes[0].get_legend_handles_labels()[0]
  44. red_patch = mpatches.Patch(color='red')
  45. green_patch = mpatches.Patch(color='green')
  46. cyan_patch = mpatches.Patch(color='cyan')
  47. handles = handles[:2] + [red_patch, green_patch, cyan_patch]
  48. labels = ["Price Up", "Price Down", "Closing Price"]
  49. axes[0].legend(handles=handles, labels=labels)
  50. # Add a box to display the current price
  51. latest_price_text = f"Current Price: ${latest_price:.2f}"
  52. box_props = dict(boxstyle='round', facecolor='white', edgecolor='black', alpha=0.8)
  53. axes[0].text(0.02, 0.95, latest_price_text, transform=axes[0].transAxes, fontsize=12, verticalalignment='top', bbox=box_props)
  54. # Define hover label format
  55. hover_label_format = [
  56. ("Open: ", lambda x: f"${x:.2f}"),
  57. ("High: ", lambda x: f"${x:.2f}"),
  58. ("Low: ", lambda x: f"${x:.2f}"),
  59. ("Close: ", lambda x: f"${x:.2f}"),
  60. ("Volume: ", lambda x: f"{int(x):,}"),
  61. ]
  62. # Function to create hover annotations
  63. def hover_annotations(data):
  64. annot = pd.DataFrame(index=data.index, columns=data.columns)
  65. annot_visible = False
  66. texts = []
  67. def onmove(event):
  68. nonlocal annot_visible
  69. if event.inaxes == axes[0]:
  70. index = int(event.xdata)
  71. if index >= len(data.index):
  72. return
  73. values = data.iloc[index]
  74. for label, formatter in hover_label_format:
  75. value = values[label.rstrip(': ')]
  76. if np.isnan(value):
  77. annot.iloc[index][label.rstrip(': ')] = ""
  78. else:
  79. annot.iloc[index][label.rstrip(': ')] = f"{label}{formatter(value)}"
  80. annot_visible = True
  81. else:
  82. annot_visible = False
  83. for t, text, (x, y) in zip(texts, annot.values, zip([event.xdata] or [], [event.ydata] or [])):
  84. if isinstance(x, (list, np.ndarray)):
  85. x = x[0] if len(x) > 0 and not np.isnan(x[0]) else None
  86. if isinstance(y, (list, np.ndarray)):
  87. y = y[0] if len(y) > 0 and not np.isnan(y[0]) else None
  88. if x is not None and y is not None:
  89. t.set_position((x, y))
  90. t.set_text('\n'.join(map(str, text)))
  91. t.set_visible(annot_visible)
  92. fig.canvas.draw_idle()
  93. for _ in data.index:
  94. t = axes[0].text(0, 0, '', visible=False, ha='left', va='top')
  95. texts.append(t)
  96. fig.canvas.mpl_connect('motion_notify_event', onmove)
  97. return annot
  98. # Attach hover annotations to the plot
  99. annotations = hover_annotations(tesla_weekly_data)
  100. # Display the chart
  101. plt.show()

If you run the code, instead of showing open high, low, close, and volume, its showing an error.

我的悬停注释为什么显示 NaN 而不是我的数值?

答案1

得分: 1

我稍微简化了你的代码。以下对我有效:

  1. import yfinance as yf
  2. import mplfinance as mpf
  3. import matplotlib.pyplot as plt
  4. import matplotlib.patches as mpatches
  5. import pandas as pd
  6. import numpy as np
  7. # 获取股票数据的日期
  8. start_date = "2020-01-01"
  9. end_date = "2023-06-15"
  10. # 获取特斯拉股票数据
  11. tesla_data = yf.download("TSLA", start=start_date, end=end_date)
  12. tesla_weekly_data = tesla_data.resample("W").agg(
  13. {"Open": "first", "High": "max", "Low": "min", "Close": "last", "Volume": "sum"}
  14. ).dropna()
  15. # 获取最新的收盘价
  16. latest_price = tesla_weekly_data['Close'][-1]
  17. # 创建附加的绘图
  18. close_price = tesla_weekly_data['Close']
  19. apd = mpf.make_addplot(close_price, color='cyan', width=2)
  20. # 绘制蜡烛图
  21. fig, axes = mpf.plot(tesla_weekly_data,
  22. type='candle',
  23. addplot=apd,
  24. style='yahoo',
  25. title='特斯拉股票价格',
  26. ylabel='价格',
  27. xlabel='日期',
  28. volume=True,
  29. ylabel_lower='交易量',
  30. volume_panel=1,
  31. figsize=(16, 8),
  32. returnfig=True
  33. )
  34. # 将y轴标签移动到左侧
  35. axes[0].yaxis.tick_left()
  36. axes[1].yaxis.tick_left()
  37. # 调整价格y轴标签的位置
  38. axes[0].yaxis.set_label_coords(-0.08, 0.5)
  39. # 调整交易量y轴标签的位置
  40. axes[1].yaxis.set_label_coords(-0.08, 0.5)
  41. # 设置价格和交易量的y轴标签
  42. axes[0].set_ylabel('价格', rotation=0, labelpad=20)
  43. axes[1].set_ylabel('交易量', rotation=0, labelpad=20)
  44. # 创建图例框
  45. handles = axes[0].get_legend_handles_labels()[0]
  46. red_patch = mpatches.Patch(color='red')
  47. green_patch = mpatches.Patch(color='green')
  48. cyan_patch = mpatches.Patch(color='cyan')
  49. handles = handles[:2] + [red_patch, green_patch, cyan_patch]
  50. labels = ["涨价", "跌价", "收盘价"]
  51. axes[0].legend(handles=handles, labels=labels)
  52. # 添加框以显示当前价格
  53. latest_price_text = f"当前价格: ${latest_price:.2f}"
  54. box_props = dict(boxstyle='round', facecolor='white', edgecolor='black', alpha=0.8)
  55. axes[0].text(0.02, 0.95, latest_price_text, transform=axes[0].transAxes,
  56. fontsize=12, verticalalignment='top', bbox=box_props)
  57. # 创建悬停注释的函数
  58. def hover_annotations(data):
  59. annot_visible = False
  60. annot = axes[0].text(0, 0, '', visible=False, ha='left', va='top')
  61. def onmove(event):
  62. nonlocal annot_visible
  63. nonlocal annot
  64. if event.inaxes == axes[0]:
  65. index = int(event.xdata)
  66. if index >= len(data.index):
  67. index = -1
  68. elif index < 0:
  69. index = 0
  70. values = data.iloc[index]
  71. mytext = (f"{values.name.date().strftime('%m/%d/%Y')}\\n"+
  72. f"O: {values['Open']:.2f}\\n"+
  73. f"H: {values['High']:.2f}\\n"+
  74. f"L: {values['Low']:.2f}\\n"+
  75. f"C: {values['Close']:.2f}\\n"+
  76. f"V: {values['Volume']:.0f}")
  77. annot_visible = True
  78. else:
  79. mytext = ''
  80. annot_visible = False
  81. annot.set_position((event.xdata,event.ydata))
  82. annot.set_text(mytext)
  83. annot.set_visible(annot_visible)
  84. fig.canvas.draw_idle()
  85. fig.canvas.mpl_connect('motion_notify_event', onmove)
  86. return annot
  87. # 将悬停注释附加到图表
  88. annotations = hover_annotations(tesla_weekly_data)
  89. # 显示图表
  90. plt.show()
英文:

I've simplified your code a little bit. The following works for me:

  1. import yfinance as yf
  2. import mplfinance as mpf
  3. import matplotlib.pyplot as plt
  4. import matplotlib.patches as mpatches
  5. import pandas as pd
  6. import numpy as np
  7. # Dates to get stock data
  8. start_date = &quot;2020-01-01&quot;
  9. end_date = &quot;2023-06-15&quot;
  10. # Fetch Tesla stock data
  11. tesla_data = yf.download(&quot;TSLA&quot;, start=start_date, end=end_date)
  12. tesla_weekly_data = tesla_data.resample(&quot;W&quot;).agg(
  13. {&quot;Open&quot;: &quot;first&quot;, &quot;High&quot;: &quot;max&quot;, &quot;Low&quot;: &quot;min&quot;, &quot;Close&quot;: &quot;last&quot;, &quot;Volume&quot;: &quot;sum&quot;}
  14. ).dropna()
  15. # Get the latest closing price
  16. latest_price = tesla_weekly_data[&#39;Close&#39;][-1]
  17. # Create additional plot
  18. close_price = tesla_weekly_data[&#39;Close&#39;]
  19. apd = mpf.make_addplot(close_price, color=&#39;cyan&#39;, width=2)
  20. # Plot the candlestick chart
  21. fig, axes = mpf.plot(tesla_weekly_data,
  22. type=&#39;candle&#39;,
  23. addplot=apd,
  24. style=&#39;yahoo&#39;,
  25. title=&#39;Tesla Stock Prices&#39;,
  26. ylabel=&#39;Price&#39;,
  27. xlabel=&#39;Date&#39;,
  28. volume=True,
  29. ylabel_lower=&#39;Volume&#39;,
  30. volume_panel=1,
  31. figsize=(16, 8),
  32. returnfig=True
  33. )
  34. # Move the y-axis labels to the left side
  35. axes[0].yaxis.tick_left()
  36. axes[1].yaxis.tick_left()
  37. # Adjust the position of the y-axis label for price
  38. axes[0].yaxis.set_label_coords(-0.08, 0.5)
  39. # Adjust the position of the y-axis label for volume
  40. axes[1].yaxis.set_label_coords(-0.08, 0.5)
  41. # Set y-axis label for price and volume
  42. axes[0].set_ylabel(&#39;Price&#39;, rotation=0, labelpad=20)
  43. axes[1].set_ylabel(&#39;Volume&#39;, rotation=0, labelpad=20)
  44. # Make the legend box
  45. handles = axes[0].get_legend_handles_labels()[0]
  46. red_patch = mpatches.Patch(color=&#39;red&#39;)
  47. green_patch = mpatches.Patch(color=&#39;green&#39;)
  48. cyan_patch = mpatches.Patch(color=&#39;cyan&#39;)
  49. handles = handles[:2] + [red_patch, green_patch, cyan_patch]
  50. labels = [&quot;Price Up&quot;, &quot;Price Down&quot;, &quot;Closing Price&quot;]
  51. axes[0].legend(handles=handles, labels=labels)
  52. # Add a box to display the current price
  53. latest_price_text = f&quot;Current Price: ${latest_price:.2f}&quot;
  54. box_props = dict(boxstyle=&#39;round&#39;, facecolor=&#39;white&#39;, edgecolor=&#39;black&#39;, alpha=0.8)
  55. axes[0].text(0.02, 0.95, latest_price_text, transform=axes[0].transAxes,
  56. fontsize=12, verticalalignment=&#39;top&#39;, bbox=box_props)
  57. # Function to create hover annotations
  58. def hover_annotations(data):
  59. annot_visible = False
  60. annot = axes[0].text(0, 0, &#39;&#39;, visible=False, ha=&#39;left&#39;, va=&#39;top&#39;)
  61. def onmove(event):
  62. nonlocal annot_visible
  63. nonlocal annot
  64. if event.inaxes == axes[0]:
  65. index = int(event.xdata)
  66. if index &gt;= len(data.index):
  67. index = -1
  68. elif index &lt; 0:
  69. index = 0
  70. values = data.iloc[index]
  71. mytext = (f&quot;{values.name.date().strftime(&#39;%m/%d/%Y&#39;):}\n&quot;+
  72. f&quot;O: {values[&#39;Open&#39;]:.2f}\n&quot;+
  73. f&quot;H: {values[&#39;High&#39;]:.2f}\n&quot;+
  74. f&quot;L: {values[&#39;Low&#39;]:.2f}\n&quot;+
  75. f&quot;C: {values[&#39;Close&#39;]:.2f}\n&quot;+
  76. f&quot;V: {values[&#39;Volume&#39;]:.0f}&quot;
  77. )
  78. annot_visible = True
  79. else:
  80. mytext = &#39;&#39;
  81. annot_visible = False
  82. annot.set_position((event.xdata,event.ydata))
  83. annot.set_text(mytext)
  84. annot.set_visible(annot_visible)
  85. fig.canvas.draw_idle()
  86. fig.canvas.mpl_connect(&#39;motion_notify_event&#39;, onmove)
  87. return annot
  88. # Attach hover annotations to the plot
  89. annotations = hover_annotations(tesla_weekly_data)
  90. # Display the chart
  91. plt.show()

I don't know what the problem was, but I completely got rid of the array of texts and the DataFrame annot (but I reused the name annot for a single annotation, what you were previously calling t). I also got rid of all the looping through these things, and the complicated formatting lambdas which seemed to me very unneccessary. At any rate, the above works for me.

huangapple
  • 本文由 发表于 2023年6月16日 09:32:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76486448.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定