英文:
Why do my hover annotations have NaN instead of my values?
问题
代码部分不需要翻译。以下是您提供的代码的翻译部分:
import yfinance as yf
import mplfinance as mpf
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import pandas as pd
import numpy as np
# 获取股票数据的日期范围
start_date = "2020-01-01"
end_date = "2023-06-15"
# 获取特斯拉股票数据
tesla_data = yf.download("TSLA", start=start_date, end=end_date)
tesla_weekly_data = tesla_data.resample("W").agg({"Open": "first", "High": "max", "Low": "min", "Close": "last", "Volume": "sum"}).dropna()
# 获取最新的收盘价
latest_price = tesla_weekly_data['Close'][-1]
# 创建额外的图表
close_price = tesla_weekly_data['Close']
apd = mpf.make_addplot(close_price, color='cyan', width=2)
# 绘制蜡烛图
fig, axes = mpf.plot(tesla_weekly_data,
type='candle',
addplot=apd,
style='yahoo',
title='特斯拉股票价格',
ylabel='价格',
xlabel='日期',
volume=True,
ylabel_lower='成交量',
volume_panel=1,
figsize=(16, 8),
returnfig=True
)
# 将y轴标签移到左侧
axes[0].yaxis.tick_left()
axes[1].yaxis.tick_left()
# 调整价格y轴标签的位置
axes[0].yaxis.set_label_coords(-0.08, 0.5)
# 调整成交量y轴标签的位置
axes[1].yaxis.set_label_coords(-0.08, 0.5)
# 设置价格和成交量的y轴标签
axes[0].set_ylabel('价格', rotation=0, labelpad=20)
axes[1].set_ylabel('成交量', rotation=0, labelpad=20)
# 创建图例框
handles = axes[0].get_legend_handles_labels()[0]
red_patch = mpatches.Patch(color='red')
green_patch = mpatches.Patch(color='green')
cyan_patch = mpatches.Patch(color='cyan')
handles = handles[:2] + [red_patch, green_patch, cyan_patch]
labels = ["涨价", "跌价", "收盘价"]
axes[0].legend(handles=handles, labels=labels)
# 添加一个框以显示当前价格
latest_price_text = f"当前价格: ${latest_price:.2f}"
box_props = dict(boxstyle='round', facecolor='white', edgecolor='black', alpha=0.8)
axes[0].text(0.02, 0.95, latest_price_text, transform=axes[0].transAxes, fontsize=12, verticalalignment='top', bbox=box_props)
# 定义悬停标签格式
hover_label_format = [
("开盘价: ", lambda x: f"${x:.2f}"),
("最高价: ", lambda x: f"${x:.2f}"),
("最低价: ", lambda x: f"${x:.2f}"),
("收盘价: ", lambda x: f"${x:.2f}"),
("成交量: ", lambda x: f"{int(x):,}"),
]
# 创建悬停注释的函数
def hover_annotations(data):
annot = pd.DataFrame(index=data.index, columns=data.columns)
annot_visible = False
texts = []
def onmove(event):
nonlocal annot_visible
if event.inaxes == axes[0]:
index = int(event.xdata)
if index >= len(data.index):
return
values = data.iloc[index]
for label, formatter in hover_label_format:
value = values[label.rstrip(': ')]
if np.isnan(value):
annot.iloc[index][label.rstrip(': ')] = ""
else:
annot.iloc[index][label.rstrip(': ')] = f"{label}{formatter(value)}"
annot_visible = True
else:
annot_visible = False
for t, text, (x, y) in zip(texts, annot.values, zip([event.xdata] or [], [event.ydata] or [])):
if isinstance(x, (list, np.ndarray)):
x = x[0] if len(x) > 0 and not np.isnan(x[0]) else None
if isinstance(y, (list, np.ndarray)):
y = y[0] if len(y) > 0 and not np.isnan(y[0]) else None
if x is not None and y is not None:
t.set_position((x, y))
t.set_text('\n'.join(map(str, text)))
t.set_visible(annot_visible)
fig.canvas.draw_idle()
for _ in data.index:
t = axes[0].text(0, 0, '', visible=False, ha='left', va='top')
texts.append(t)
fig.canvas.mpl_connect('motion_notify_event', onmove)
return annot
# 将悬停注释附加到图表
annotations = hover_annotations(tesla_weekly_data)
# 显示图表
plt.show()
如果您运行此代码,它将绘制特斯拉股票的蜡烛图,并提供悬停功能,以显示开盘价、最高价、最低价、收盘价和成交量的信息。
英文:
import yfinance as yf
import mplfinance as mpf
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import pandas as pd
import numpy as np
# Dates to get stock data
start_date = "2020-01-01"
end_date = "2023-06-15"
# Fetch Tesla stock data
tesla_data = yf.download("TSLA", start=start_date, end=end_date)
tesla_weekly_data = tesla_data.resample("W").agg({"Open": "first", "High": "max", "Low": "min", "Close": "last", "Volume": "sum"}).dropna()
# Get the latest closing price
latest_price = tesla_weekly_data['Close'][-1]
# Create additional plot
close_price = tesla_weekly_data['Close']
apd = mpf.make_addplot(close_price, color='cyan', width=2)
# Plot the candlestick chart
fig, axes = mpf.plot(tesla_weekly_data,
type='candle',
addplot=apd,
style='yahoo',
title='Tesla Stock Prices',
ylabel='Price',
xlabel='Date',
volume=True,
ylabel_lower='Volume',
volume_panel=1,
figsize=(16, 8),
returnfig=True
)
# Move the y-axis labels to the left side
axes[0].yaxis.tick_left()
axes[1].yaxis.tick_left()
# Adjust the position of the y-axis label for price
axes[0].yaxis.set_label_coords(-0.08, 0.5)
# Adjust the position of the y-axis label for volume
axes[1].yaxis.set_label_coords(-0.08, 0.5)
# Set y-axis label for price and volume
axes[0].set_ylabel('Price', rotation=0, labelpad=20)
axes[1].set_ylabel('Volume', rotation=0, labelpad=20)
# Make the legend box
handles = axes[0].get_legend_handles_labels()[0]
red_patch = mpatches.Patch(color='red')
green_patch = mpatches.Patch(color='green')
cyan_patch = mpatches.Patch(color='cyan')
handles = handles[:2] + [red_patch, green_patch, cyan_patch]
labels = ["Price Up", "Price Down", "Closing Price"]
axes[0].legend(handles=handles, labels=labels)
# Add a box to display the current price
latest_price_text = f"Current Price: ${latest_price:.2f}"
box_props = dict(boxstyle='round', facecolor='white', edgecolor='black', alpha=0.8)
axes[0].text(0.02, 0.95, latest_price_text, transform=axes[0].transAxes, fontsize=12, verticalalignment='top', bbox=box_props)
# Define hover label format
hover_label_format = [
("Open: ", lambda x: f"${x:.2f}"),
("High: ", lambda x: f"${x:.2f}"),
("Low: ", lambda x: f"${x:.2f}"),
("Close: ", lambda x: f"${x:.2f}"),
("Volume: ", lambda x: f"{int(x):,}"),
]
# Function to create hover annotations
def hover_annotations(data):
annot = pd.DataFrame(index=data.index, columns=data.columns)
annot_visible = False
texts = []
def onmove(event):
nonlocal annot_visible
if event.inaxes == axes[0]:
index = int(event.xdata)
if index >= len(data.index):
return
values = data.iloc[index]
for label, formatter in hover_label_format:
value = values[label.rstrip(': ')]
if np.isnan(value):
annot.iloc[index][label.rstrip(': ')] = ""
else:
annot.iloc[index][label.rstrip(': ')] = f"{label}{formatter(value)}"
annot_visible = True
else:
annot_visible = False
for t, text, (x, y) in zip(texts, annot.values, zip([event.xdata] or [], [event.ydata] or [])):
if isinstance(x, (list, np.ndarray)):
x = x[0] if len(x) > 0 and not np.isnan(x[0]) else None
if isinstance(y, (list, np.ndarray)):
y = y[0] if len(y) > 0 and not np.isnan(y[0]) else None
if x is not None and y is not None:
t.set_position((x, y))
t.set_text('\n'.join(map(str, text)))
t.set_visible(annot_visible)
fig.canvas.draw_idle()
for _ in data.index:
t = axes[0].text(0, 0, '', visible=False, ha='left', va='top')
texts.append(t)
fig.canvas.mpl_connect('motion_notify_event', onmove)
return annot
# Attach hover annotations to the plot
annotations = hover_annotations(tesla_weekly_data)
# Display the chart
plt.show()
If you run the code, instead of showing open high, low, close, and volume, its showing an error.
答案1
得分: 1
我稍微简化了你的代码。以下对我有效:
import yfinance as yf
import mplfinance as mpf
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import pandas as pd
import numpy as np
# 获取股票数据的日期
start_date = "2020-01-01"
end_date = "2023-06-15"
# 获取特斯拉股票数据
tesla_data = yf.download("TSLA", start=start_date, end=end_date)
tesla_weekly_data = tesla_data.resample("W").agg(
{"Open": "first", "High": "max", "Low": "min", "Close": "last", "Volume": "sum"}
).dropna()
# 获取最新的收盘价
latest_price = tesla_weekly_data['Close'][-1]
# 创建附加的绘图
close_price = tesla_weekly_data['Close']
apd = mpf.make_addplot(close_price, color='cyan', width=2)
# 绘制蜡烛图
fig, axes = mpf.plot(tesla_weekly_data,
type='candle',
addplot=apd,
style='yahoo',
title='特斯拉股票价格',
ylabel='价格',
xlabel='日期',
volume=True,
ylabel_lower='交易量',
volume_panel=1,
figsize=(16, 8),
returnfig=True
)
# 将y轴标签移动到左侧
axes[0].yaxis.tick_left()
axes[1].yaxis.tick_left()
# 调整价格y轴标签的位置
axes[0].yaxis.set_label_coords(-0.08, 0.5)
# 调整交易量y轴标签的位置
axes[1].yaxis.set_label_coords(-0.08, 0.5)
# 设置价格和交易量的y轴标签
axes[0].set_ylabel('价格', rotation=0, labelpad=20)
axes[1].set_ylabel('交易量', rotation=0, labelpad=20)
# 创建图例框
handles = axes[0].get_legend_handles_labels()[0]
red_patch = mpatches.Patch(color='red')
green_patch = mpatches.Patch(color='green')
cyan_patch = mpatches.Patch(color='cyan')
handles = handles[:2] + [red_patch, green_patch, cyan_patch]
labels = ["涨价", "跌价", "收盘价"]
axes[0].legend(handles=handles, labels=labels)
# 添加框以显示当前价格
latest_price_text = f"当前价格: ${latest_price:.2f}"
box_props = dict(boxstyle='round', facecolor='white', edgecolor='black', alpha=0.8)
axes[0].text(0.02, 0.95, latest_price_text, transform=axes[0].transAxes,
fontsize=12, verticalalignment='top', bbox=box_props)
# 创建悬停注释的函数
def hover_annotations(data):
annot_visible = False
annot = axes[0].text(0, 0, '', visible=False, ha='left', va='top')
def onmove(event):
nonlocal annot_visible
nonlocal annot
if event.inaxes == axes[0]:
index = int(event.xdata)
if index >= len(data.index):
index = -1
elif index < 0:
index = 0
values = data.iloc[index]
mytext = (f"{values.name.date().strftime('%m/%d/%Y')}\\n"+
f"O: {values['Open']:.2f}\\n"+
f"H: {values['High']:.2f}\\n"+
f"L: {values['Low']:.2f}\\n"+
f"C: {values['Close']:.2f}\\n"+
f"V: {values['Volume']:.0f}")
annot_visible = True
else:
mytext = ''
annot_visible = False
annot.set_position((event.xdata,event.ydata))
annot.set_text(mytext)
annot.set_visible(annot_visible)
fig.canvas.draw_idle()
fig.canvas.mpl_connect('motion_notify_event', onmove)
return annot
# 将悬停注释附加到图表
annotations = hover_annotations(tesla_weekly_data)
# 显示图表
plt.show()
英文:
I've simplified your code a little bit. The following works for me:
import yfinance as yf
import mplfinance as mpf
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import pandas as pd
import numpy as np
# Dates to get stock data
start_date = "2020-01-01"
end_date = "2023-06-15"
# Fetch Tesla stock data
tesla_data = yf.download("TSLA", start=start_date, end=end_date)
tesla_weekly_data = tesla_data.resample("W").agg(
{"Open": "first", "High": "max", "Low": "min", "Close": "last", "Volume": "sum"}
).dropna()
# Get the latest closing price
latest_price = tesla_weekly_data['Close'][-1]
# Create additional plot
close_price = tesla_weekly_data['Close']
apd = mpf.make_addplot(close_price, color='cyan', width=2)
# Plot the candlestick chart
fig, axes = mpf.plot(tesla_weekly_data,
type='candle',
addplot=apd,
style='yahoo',
title='Tesla Stock Prices',
ylabel='Price',
xlabel='Date',
volume=True,
ylabel_lower='Volume',
volume_panel=1,
figsize=(16, 8),
returnfig=True
)
# Move the y-axis labels to the left side
axes[0].yaxis.tick_left()
axes[1].yaxis.tick_left()
# Adjust the position of the y-axis label for price
axes[0].yaxis.set_label_coords(-0.08, 0.5)
# Adjust the position of the y-axis label for volume
axes[1].yaxis.set_label_coords(-0.08, 0.5)
# Set y-axis label for price and volume
axes[0].set_ylabel('Price', rotation=0, labelpad=20)
axes[1].set_ylabel('Volume', rotation=0, labelpad=20)
# Make the legend box
handles = axes[0].get_legend_handles_labels()[0]
red_patch = mpatches.Patch(color='red')
green_patch = mpatches.Patch(color='green')
cyan_patch = mpatches.Patch(color='cyan')
handles = handles[:2] + [red_patch, green_patch, cyan_patch]
labels = ["Price Up", "Price Down", "Closing Price"]
axes[0].legend(handles=handles, labels=labels)
# Add a box to display the current price
latest_price_text = f"Current Price: ${latest_price:.2f}"
box_props = dict(boxstyle='round', facecolor='white', edgecolor='black', alpha=0.8)
axes[0].text(0.02, 0.95, latest_price_text, transform=axes[0].transAxes,
fontsize=12, verticalalignment='top', bbox=box_props)
# Function to create hover annotations
def hover_annotations(data):
annot_visible = False
annot = axes[0].text(0, 0, '', visible=False, ha='left', va='top')
def onmove(event):
nonlocal annot_visible
nonlocal annot
if event.inaxes == axes[0]:
index = int(event.xdata)
if index >= len(data.index):
index = -1
elif index < 0:
index = 0
values = data.iloc[index]
mytext = (f"{values.name.date().strftime('%m/%d/%Y'):}\n"+
f"O: {values['Open']:.2f}\n"+
f"H: {values['High']:.2f}\n"+
f"L: {values['Low']:.2f}\n"+
f"C: {values['Close']:.2f}\n"+
f"V: {values['Volume']:.0f}"
)
annot_visible = True
else:
mytext = ''
annot_visible = False
annot.set_position((event.xdata,event.ydata))
annot.set_text(mytext)
annot.set_visible(annot_visible)
fig.canvas.draw_idle()
fig.canvas.mpl_connect('motion_notify_event', onmove)
return annot
# Attach hover annotations to the plot
annotations = hover_annotations(tesla_weekly_data)
# Display the chart
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论