Я пытаюсь создать код Python, чтобы показать линейный график c с помощью matlibplot, и в то же время показывает информацию о x и y в разбросанных точках. Я нашел этот код, и это в значительной степени то, что я хочу сделать:
import matplotlib.pyplot as plt
def update_annot(ind, line, annot, ydata):
x, y = line.get_data()
annot.xy = (x[ind["ind"][0]], y[ind["ind"][0]])
# Get x and y values, then format them to be displayed
x_values = " ".join(list(map(str, ind["ind"])))
y_values = " ".join(str(ydata[n]) for n in ind["ind"])
text = "{}, {}".format(x_values, y_values)
annot.set_text(text)
annot.get_bbox_patch().set_alpha(0.4)
def hover(event, line_info):
line, annot, ydata = line_info
vis = annot.get_visible()
if event.inaxes == ax:
# Draw annotations if cursor in right position
print(dir(line))
cont, ind = line.contains(event)
if cont:
update_annot(ind, line, annot, ydata)
annot.set_visible(True)
fig.canvas.draw_idle()
else:
# Don't draw annotations
if vis:
annot.set_visible(False)
fig.canvas.draw_idle()
def plot_line(x, y):
line, = plt.plot(x, y, marker="o")
# Annotation style may be changed here
annot = ax.annotate("", xy=(0, 0), xytext=(-20, 20), textcoords="offset points",bbox=dict(boxstyle="round", fc="w"),arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)
line_info = [line, annot, y]
fig.canvas.mpl_connect("motion_notify_event",lambda event: hover(event, line_info))
# Your data values to plot
x1 = range(21)
y1 = range(0, 21)
x2 = range(21)
y2 = range(0, 42, 2)
# Plot line graphs
fig, ax = plt.subplots()
plot_line(x1, y1)
#plot_line(x2, y2)
plt.show()
Он работает нормально со случайными данными, но когда я пытаюсь сделать то же самое с реальными данными, поступающими из файла с информацией о разных столбцах, я получаю ошибки. Это код, который я использую:
import time
from datetime import datetime,timedelta
import subprocess
import sys
import os
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import style
def grafico():
grafico = "1"
if grafico =="1":
input_indice="1"
x=[]
y=[]
style.use("ggplot")
input_año="2020"
input_año=int(input_año)
input_mes = "01"
# GRÁFICO PARA IBEX35
if input_indice =="1":
input_año = str(input_año)
dt = pd.read_csv('~/Test.txt', delimiter=',')
dt_fecha = dt.loc[dt['Date'].str.contains(input_año + "-" + input_mes)]
fecha=dt_fecha.Date
for row in fecha:
fecha=row[5:]
x.append(fecha)
apertura=dt_fecha.Open
for row in apertura:
apertura=row
y.append(apertura)
def update_annot(ind, line, annot, ydata):
x, y = line.get_data()
annot.xy = (x[ind["ind"][0]], y[ind["ind"][0]])
x_values = " ".join(list(map(str, ind["ind"])))
y_values = " ".join(str(ydata[n]) for n in ind["ind"])
text = "{}, {}".format(x_values, y_values)
annot.set_text(text)
annot.get_bbox_patch().set_alpha(0.4)
def hover(event, line_info):
line, annot, ydata = line_info
vis = annot.get_visible()
if event.inaxes == ax:
print(dir(line))
cont, ind = line.contains(event)
if cont:
update_annot(ind, line, annot, ydata)
annot.set_visible(True)
fig.canvas.draw_idle()
else:
if vis:
annot.set_visible(False)
fig.canvas.draw_idle()
fig, ax = plt.subplots()
line=plt.plot(x,y,color="red", marker="o")
annot = ax.annotate("", xy=(0, 0), xytext=(-20, 20), textcoords="offset points",bbox=dict(boxstyle="round", fc="w"),arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)
line_info = [line, annot, y]
fig.canvas.mpl_connect("motion_notify_event",lambda event: hover(event, line_info))
plt.show()
sys.exit()
while True:
grafico()
Данные в файле Test.txt следующие:
Date,Open,High,Low,Close,Volume,Dividends,Stock Splits
2020-01-02,9639.1,9705.4,9615.1,9691.2,142379600,0,0
2020-01-03,9631.2,9650.7,9581.2,9646.6,135130000,0,0
2020-01-06,9585.4,9618.2,9492.7,9600.9,103520400,0,0
2020-01-07,9623.1,9657.9,9557.9,9579.8,133476100,0,0
График c отображается, но когда я двигаюсь указав мышью на некоторые из разбросанных точек, я получаю сообщение об ошибке: cont, ind = line.contains (event) AttributeError: объект 'list' не имеет атрибута 'contains'
Пример, который работает, использует диапазон для отображения на графике c, но мои данные не являются типом диапазона, это тип списка. Не могли бы вы помочь мне с этим? Большое спасибо.