我是matplotlib的新手,我正在努力学习这里的工作。
我在一段时间内拥有机器人的XY坐标,我想绘制这些点以显示机器人的运动。下面的代码(这可能是其他堆栈溢出专家的慷慨)提供了坐标的散点图。但是,我真的只想要最后30个条目。每个坐标都来自视频帧。视频是每秒30帧。我想绘制最后一秒,以便我可以想象运动。绘制的每个坐标应在1/30秒后消失。
说coords列表有1800个点,代表60秒的数据。我想从列表的开头绘制,每1/30秒绘制一个点,当绘图上的点数达到30时,在绘制第31个索引之前,从绘图中删除第0个索引点,因此从coords列表的每个连续点,直到结束。我认为这将模拟机器人正在移动,在最后1秒内留下其点的踪迹。
我不知道如何绘制一个点,并在绘制新点之后让它在一段时间后从帧中消失。这将模拟一个动作。
# read_data() returns a list of tuples of xy coordinates
coords = read_data()
x_list = [int(pt[0]) for pt in coords]
y_list = [int(pt[1]) for pt in coords]
x_min, x_max = min(x_list), max(x_list)
y_min, y_max = min(y_list), max(y_list)
fig=plt.figure()
ax1 = fig.add_subplot(111)
ax1.add_patch( # draw the bounday of the robot movements based on the min and max of coordinates
patches.Rectangle(
(x_min, y_min), # (x,y)
x_max - x_min, # width
y_max - y_min, # height
linewidth=0.1,
fill=False
)
)
ax1.plot(x_list, y_list, 'or', linewidth=0, markersize=0.2) # plot the whole set
# what I really need is just the last 30 entries; each entry comes in 1/30th of a second in actual env
答案 0 :(得分:0)
我最近遇到了类似的问题,因为我需要说明一些运动跟踪数据。我以为您以另一种方式解决了这个问题(恭喜!),但是为了后代的缘故,将其保留在这里。
我最终将其与Dash(https://plotly.com/dash/)配合使用。
如果将数据框“ df”中的值替换为x和y,则应该具有可以执行您所要求的功能(我认为)。如果您用数据替换了列表x和列表y的内容,那么您应该能够获得所需的内容。
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import numpy as np
import random
# defining the number of steps
n = 3000
#creating two arrays for containing x and y coordinate -- these are the lists you need to change
#of size equals to the number of size and filled up with 0's
x = 100 + np.zeros(n)
y = 100 + np.zeros(n)
# filling the coordinates with random variables
for i in range(1, n):
val = random.randint(1, 4)
if val == 1:
x[i] = x[i - 1] + 1
y[i] = y[i - 1]
elif val == 2:
x[i] = x[i - 1] - 1
y[i] = y[i - 1]
elif val == 3:
x[i] = x[i - 1]
y[i] = y[i - 1] + 1
else:
x[i] = x[i - 1]
y[i] = y[i - 1] - 1
df = {'X': x, 'Y': y, 'Sample no.': [ind+1 for ind, x in enumerate(x)]}
indx=[ind for ind, x in enumerate(df['Y'])]
time_df = pd.DataFrame({"time": [0], "df_len": [len(df['X'])]})
def df_cond(series, last_n, tail):
if last_n < tail:
s = series[0: last_n]
else:
s = series[(last_n-tail): last_n]
return s
def change(dataframe, size):
try:
dataframe['time'][0] = dataframe['time'][0] + int(size)
return dataframe['time'][0]
except:
return dataframe['time'][0]
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.Div([
html.Div([
dcc.Input(id='auto_speed', value=1, type='number'),
], className="two columns"),
html.Div([
dcc.Input(id='trail', value=100, type='number'),
], className="two columns"),
html.Div([
dcc.Input(id='man_start', value=0, type='number'),
], className="two columns"),
html.Div([
dcc.Input(id='man_end', value=0, type='number'),
], className="two columns"),
], className="row"),
html.Div([
html.Div([
html.Div(id='auto_description'),
], className="six columns"),
html.Div([
html.Div(id='man_description')
], className="six columns"),
], className="row"),
dcc.Interval(
id='interval-component',
interval=1*1000, # in milliseconds
n_intervals=0
),
html.Div([
html.Div([
dcc.Graph(id='behaviour', style={'width': 950, 'height': 950}, ),
], className="six columns"),
html.Div([
dcc.Graph(
id='behaviour_full',
style={'width': 950, 'height': 950},
figure={
'data': [
dict(
x=df['X'],
y=df['Y'],
hovertext="xs and ys",
hoverinfo="text",
showlegend = True,
name = "Sample nr: {} - {} of {}".format(0, len(df['X']), len(df['X'])),
mode='markers',
opacity=0.7,
marker={
'size': 5,
'line': {'width': 0.5, 'color': 'white'}
}
)
],
'layout': dict(
xaxis={'type': 'linear', 'title': 'x-positions', 'range': [0,200]},
yaxis={'type': 'linear','title': 'y-positions', 'range': [0,200]},
hovermode='closest',
transition = {'duration': 1}
)
})
], className="six columns"),
], className="row"),
# Hidden div inside the app that stores the intermediate value
html.Div(id='intermediate-value', style={'display': 'none'})
])
#callbacks are activated, when they receive input -- so a callback including an interval-component, will update at the interval-component update-rate
@app.callback(
Output('intermediate-value', 'children'),
[Input('interval-component', 'n_intervals'),
Input('auto_speed', component_property='value'),
Input(component_id='man_start', component_property='value'),
Input(component_id='man_end', component_property='value')]
)
def clean_data(value, size, man_start, man_end):
if man_start == -1:
time_df['time'][0] = man_end
print("zeroed")
return time_df['time'][0]
elif type(man_start) is int and type(man_end) is int and (man_end - man_start) > 0:
return change(time_df, 0)
else:
return change(time_df, size)
@app.callback(
Output(component_id='behaviour', component_property='figure'),
[Input(component_id='auto_speed', component_property='value'),
Input('intermediate-value', 'children'),
Input(component_id='trail', component_property='value'),
Input(component_id='man_start', component_property='value'),
Input(component_id='man_end', component_property='value'),]
)
def update_figure(interval, last_n, tail, man_start, man_end):
if type(man_start) is int and type(man_end) is int and (man_end - man_start) > 0:
return {
'data': [
dict(
x=df['X'][man_start: man_end],
y=df['Y'][man_start: man_end],
hovertext=["X: {}<br>Y: {}<br>Sample: {}".format(df['X'][man_start: man_end][i], df['Y'][man_start: man_end][i], indx[i]+1) for i in indx[man_start: man_end]],
hoverinfo="text",
showlegend = True,
name = "Sample nr: {} - {} of {} <br>{}".format(man_start, man_end, len(df['X']), interval),
mode='markers',
opacity=0.7,
marker={
'size': 5,
'line': {'width': 0.5, 'color': 'white'}
}
)
],
'layout': dict(
xaxis={'type': 'linear', 'title': 'x-positions', 'range': [0,200]},
yaxis={'type': 'linear','title': 'y-positions', 'range': [0,200]},
hovermode='closest',
uirevision= 'dataset',
transition = {'duration': 1}
)
}
else:
if last_n is None:
last_n = 0
return {
'data': [
dict(
x=df_cond(df['X'], last_n, tail),
y=df_cond(df['Y'], last_n, tail),
hovertext=["X: {}<br>Y: {}<br>Sample: {}".format(df['X'][i-1], df['Y'][i-1], df['Sample no.'][i-1]) for i in df_cond(df['Sample no.'], last_n, tail)],
hoverinfo="text",
showlegend = True,
name = "Sample nr: {} - {} of {} <br>{}".format(last_n - len(df_cond(df['X'], last_n, tail))+1, last_n, len(df['X']), interval),
mode='markers',
opacity=0.7,
marker={
'size': 5,
'line': {'width': 0.5, 'color': 'white'}
}
)
],
'layout': dict(
xaxis={'type': 'linear', 'title': 'x-positions', 'range': [0,200]},
yaxis={'type': 'linear','title': 'y-positions', 'range': [0,200]},
hovermode='closest',
uirevision= 'dataset',
transition = {'duration': 1}
)
}
@app.callback(
Output(component_id='auto_description', component_property='children'),
[Input(component_id='auto_speed', component_property='value'),
Input('interval-component', 'n_intervals'),
Input(component_id='man_start', component_property='value'),
Input(component_id='man_end', component_property='value'),
Input(component_id='trail', component_property='value')]
)
def update_output_div(input_value, n_intervals, man_start, man_end, tail):
if man_start == -1:
return ' Auto sample index set to: {}'.format(man_end)
elif type(man_start) is int and type(man_end) is int and (man_end - man_start) > 0:
return ' Manual values being used.'
else:
if tail > time_df['time'][0]:
return ' Automatic slice: {} - {}'.format(0, time_df['time'][0])
else:
return ' Automatic slice: {} - {}'.format(time_df['time'][0]-tail, int(time_df['time'][0]))
@app.callback(
Output(component_id='man_description', component_property='children'),
[Input(component_id='man_start', component_property='value'),
Input(component_id='man_end', component_property='value')]
)
def update_output_div(start_val, end_val):
if start_val is None:
return ' Using auto slice'
elif start_val == -1:
return ' Setting auto sample index to: {}'.format(end_val)
elif end_val - start_val > 0:
return ' Manual slice: {} - {}'.format(start_val, end_val)
else:
return ' Using auto slice'
if __name__ == '__main__':
app.run_server(debug=True)
您可以通过在终端中的“在http://(...)上运行”行中输入地址来查看插图。
适当的让点从框架中消失-在此脚本中所做的基本上只是重新绘制示例数据的新部分。我相当确定我的解决方案效率很低。但这确实满足了我的需要。