【发布时间】:2015-10-03 19:46:33
【问题描述】:
我正在使用 seaborn 包创建一个交互式图表。 这是一个简单的图表,x 轴为日期,y 轴为 0 到 5 的值 我可以使用箭头键左右移动光标条,并使用 num 键设置图表的 y 值(并将图表的 y 值及其时间戳导出到 csv)。 但是,当使用较大的日期范围时,程序会变得异常缓慢。 我按箭头键将光标移动一格,但可能需要一到两秒才能做出反应。 (关键控制是用PyQT完成的) 知道我可以做些什么来加快速度吗?
请随意复制粘贴代码并在python中运行以查看程序:
import matplotlib.pyplot as plt
import matplotlib
import pandas as pd
from datetime import timedelta, date
import numpy as np
matplotlib.use('Qt4Agg')
import seaborn as sns
from matplotlib.widgets import Button
import matplotlib.lines
from matplotlib.lines import Line2D
import csv
from itertools import izip
dates = []
values = []
sns.set(style="ticks")
fig = plt.figure(1, figsize=(25,7))
fig.clf()
ax = fig.add_subplot(111)
fig.canvas.draw()
plt.ylim(0,5)
horizontal_position = 0
periods = 365
idx = pd.DatetimeIndex(start='2010-01-01', freq='d', periods=periods)
index_delete = []
for i in range(idx.size):
if idx[i].dayofweek == 6 or idx[i].dayofweek == 5:
index_delete.append(i)
idx = idx.delete(index_delete)
periods = idx.size
idx_x_array = np.array(range(idx.size), dtype=np.int32)
str_vals = []
first_day_lines = []
counter = 0
if periods > 170:
for s in idx._data:
s = str(s)
day = s[8:10]
month = s[5:7]
year = s[0:4]
if day == '01':
dotted_line_f = plt.Line2D((counter, counter), (0, 5), lw=2., marker='.',
color='gray')
first_day_lines.append(dotted_line_f)
date_str = day+'/'+month+'/'+year
str_vals.append(date_str)
elif idx.dayofweek[counter]:
date_str = day+'/'+month
str_vals.append(date_str)
else:
str_vals.append('')
counter +=1
if periods <= 170:
for s in idx._data:
s = str(s)
day = s[8:10]
month = s[5:7]
year = s[0:4]
if day == '01':
dotted_line_f = plt.Line2D((counter, counter), (0, 5), lw=2., marker='.',
color='gray')
first_day_lines.append(dotted_line_f)
date_str = day+'/'+month+'/'+year
str_vals.append(date_str)
else:
date_str = day+'/'+month
str_vals.append(date_str)
counter +=1
plt.grid(True)
plt.xticks(idx_x_array, str_vals, rotation='vertical', fontsize=7)
values = []
for i in idx_x_array:
values.append(0)
data= pd.DataFrame({('A','a'):values}, idx)
sns.set_context(context={"figure.figsize":(5,5)})
ab = sns.tsplot(data.T.values, idx_x_array)
ab.lines[0].set_color('red')
# x_len = len(ab.lines[0]._x)
ab.lines[0]._x = idx_x_array
dotted_line = plt.Line2D((1, 1), (0, 5), lw=2.,
ls='-.', marker='.',
markersize=1,
color='black',
markerfacecolor='black',
markeredgecolor='black',
alpha=0.5)
ab.add_line(dotted_line)
for line in first_day_lines:
ab.add_line(line)
lines = ab.lines
init_focus = ab.lines[0]
index_focus = 0
bbox_props = dict(boxstyle="rarrow,pad=0.3", fc="pink", ec="b", lw=2)
horizontal_position = init_focus._x[index_focus]
plt.subplots_adjust(bottom=.30, left=.03, right=.97, top=.90, hspace=.35)
analysis_label = 'Analysis mode'
discovery_label = 'Discovery mode'
def chart_mode(event):
global button_label
global dotted_line
global power
global horizontal_position
global index_focus
global dotted_line
global idx
if button_label == analysis_label:
index_focus = 0
button_label = discovery_label
plt.draw()
elif button_label == discovery_label:
index_focus = periods-1
button_label = analysis_label
plt.draw()
bnext.label.set_text(button_label)
horizontal_position = ab.lines[0]._x[index_focus]
dotted_line = plt.Line2D((horizontal_position,horizontal_position), (0, 5), lw=5.,
ls='-.', marker='.',
markersize=1,
color='black',
markerfacecolor='black',
markeredgecolor='black',
alpha=0.5)
ax.add_line(dotted_line)
new_line = ax.lines.pop()
ax.lines[1] = new_line
def export_csv(event):
x_data = idx._data
y_data = ab.lines[0]._y
x_data_proc = []
for x in x_data:
x = str(x)
day = x[8:10]
month = x[5:7]
year = x[0:4]
date_str = day+'/'+month
x_data_proc.append(date_str)
y_data_proc = []
for y in y_data:
y_data_proc.append(int(y))
with open('some.csv', 'wb') as f:
writer = csv.writer(f)
writer.writerows(izip(x_data_proc, y_data_proc))
button_label = analysis_label
axnext = plt.axes([0.1, 0.05, 0.1, 0.075])
bnext = Button(axnext, button_label)
bnext.on_clicked(chart_mode)
axexport = plt.axes([0.21, 0.05, 0.1, 0.075])
bexport = Button(axexport, 'export csv')
bexport.on_clicked(export_csv)
def on_keyboard(event):
global power
global horizontal_position
global index_focus
global dotted_line
global idx
if event.key == 'right':
if index_focus < periods-1:
index_focus+=1
else:
idx = idx + timedelta(days=1)
index_focus+=1
elif event.key == 'left':
if index_focus > 0:
index_focus-=1
elif event.key == 'up':
if index_focus < periods-5:
index_focus+=5
elif event.key == 'down':
if index_focus > 5:
index_focus-=5
elif is_number(event.key):
for i in range(len(ab.lines[0]._y[index_focus::])):
ab.lines[0]._y[index_focus+i] = event.key
horizontal_position = ab.lines[0]._x[index_focus]
dotted_line = plt.Line2D((horizontal_position,horizontal_position), (0, 5), lw=2.,
ls='-.', marker='.',
markersize=1,
color='black',
markerfacecolor='black',
markeredgecolor='black',
alpha=0.5)
ax.add_line(dotted_line)
new_line = ax.lines.pop()
ax.lines[1] = new_line
fig.canvas.draw()
plt.show()
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
plt.gcf().canvas.mpl_connect('key_press_event', on_keyboard)
plt.show()
【问题讨论】:
标签: python csv numpy matplotlib seaborn