graphstats: Add support for interactive graphs
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
0173bb3f71
commit
8cce3cc8e7
|
@ -147,7 +147,7 @@ sudo apt-get install python-matplotlib
|
||||||
Then graphs can be produced with:
|
Then graphs can be produced with:
|
||||||
|
|
||||||
```
|
```
|
||||||
~/klipper/scripts/graphstats.py /tmp/klippy.log loadgraph.png
|
~/klipper/scripts/graphstats.py /tmp/klippy.log -o loadgraph.png
|
||||||
```
|
```
|
||||||
|
|
||||||
One can then view the resulting **loadgraph.png** file.
|
One can then view the resulting **loadgraph.png** file.
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# Script to parse a logging file, extract the stats, and graph them
|
# Script to parse a logging file, extract the stats, and graph them
|
||||||
#
|
#
|
||||||
# Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
# Copyright (C) 2016-2019 Kevin O'Connor <kevin@koconnor.net>
|
||||||
#
|
#
|
||||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
import optparse, datetime
|
import optparse, datetime
|
||||||
import matplotlib
|
import matplotlib
|
||||||
matplotlib.use('Agg')
|
|
||||||
import matplotlib.pyplot, matplotlib.dates, matplotlib.font_manager
|
|
||||||
import matplotlib.ticker
|
|
||||||
|
|
||||||
MAXBANDWIDTH=25000.
|
MAXBANDWIDTH=25000.
|
||||||
MAXBUFFER=2.
|
MAXBUFFER=2.
|
||||||
|
@ -53,6 +50,12 @@ def parse_log(logname, mcu):
|
||||||
f.close()
|
f.close()
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
def setup_matplotlib(output_to_file):
|
||||||
|
if output_to_file:
|
||||||
|
matplotlib.use('Agg')
|
||||||
|
import matplotlib.pyplot, matplotlib.dates, matplotlib.font_manager
|
||||||
|
import matplotlib.ticker
|
||||||
|
|
||||||
def find_print_restarts(data):
|
def find_print_restarts(data):
|
||||||
runoff_samples = {}
|
runoff_samples = {}
|
||||||
last_runoff_start = last_buffer_time = last_sampletime = 0.
|
last_runoff_start = last_buffer_time = last_sampletime = 0.
|
||||||
|
@ -81,7 +84,7 @@ def find_print_restarts(data):
|
||||||
for sampletime in samples if not stall}
|
for sampletime in samples if not stall}
|
||||||
return sample_resets
|
return sample_resets
|
||||||
|
|
||||||
def plot_mcu(data, maxbw, outname):
|
def plot_mcu(data, maxbw):
|
||||||
# Generate data for plot
|
# Generate data for plot
|
||||||
basetime = lasttime = data[0]['#sampletime']
|
basetime = lasttime = data[0]['#sampletime']
|
||||||
lastbw = float(data[0]['bytes_write']) + float(data[0]['bytes_retransmit'])
|
lastbw = float(data[0]['bytes_write']) + float(data[0]['bytes_retransmit'])
|
||||||
|
@ -131,10 +134,9 @@ def plot_mcu(data, maxbw, outname):
|
||||||
ax1.legend(loc='best', prop=fontP)
|
ax1.legend(loc='best', prop=fontP)
|
||||||
ax1.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%H:%M'))
|
ax1.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%H:%M'))
|
||||||
ax1.grid(True)
|
ax1.grid(True)
|
||||||
fig.set_size_inches(8, 6)
|
return fig
|
||||||
fig.savefig(outname)
|
|
||||||
|
|
||||||
def plot_frequency(data, outname, mcu):
|
def plot_frequency(data, mcu):
|
||||||
all_keys = {}
|
all_keys = {}
|
||||||
for d in data:
|
for d in data:
|
||||||
all_keys.update(d)
|
all_keys.update(d)
|
||||||
|
@ -167,10 +169,9 @@ def plot_frequency(data, outname, mcu):
|
||||||
ax1.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%H:%M'))
|
ax1.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%H:%M'))
|
||||||
ax1.yaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter('%d'))
|
ax1.yaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter('%d'))
|
||||||
ax1.grid(True)
|
ax1.grid(True)
|
||||||
fig.set_size_inches(8, 6)
|
return fig
|
||||||
fig.savefig(outname)
|
|
||||||
|
|
||||||
def plot_temperature(data, outname, heater):
|
def plot_temperature(data, heater):
|
||||||
temp_key = heater + ':' + 'temp'
|
temp_key = heater + ':' + 'temp'
|
||||||
target_key = heater + ':' + 'target'
|
target_key = heater + ':' + 'target'
|
||||||
pwm_key = heater + ':' + 'pwm'
|
pwm_key = heater + ':' + 'pwm'
|
||||||
|
@ -201,32 +202,45 @@ def plot_temperature(data, outname, heater):
|
||||||
ax1.legend(loc='best', prop=fontP)
|
ax1.legend(loc='best', prop=fontP)
|
||||||
ax1.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%H:%M'))
|
ax1.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%H:%M'))
|
||||||
ax1.grid(True)
|
ax1.grid(True)
|
||||||
fig.set_size_inches(8, 6)
|
return fig
|
||||||
fig.savefig(outname)
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
usage = "%prog [options] <logfile> <outname>"
|
# Parse command-line arguments
|
||||||
|
usage = "%prog [options] <logfile>"
|
||||||
opts = optparse.OptionParser(usage)
|
opts = optparse.OptionParser(usage)
|
||||||
opts.add_option("-f", "--frequency", action="store_true",
|
opts.add_option("-f", "--frequency", action="store_true",
|
||||||
help="graph mcu frequency")
|
help="graph mcu frequency")
|
||||||
|
opts.add_option("-o", "--output", type="string", dest="output",
|
||||||
|
default=None, help="filename of output graph")
|
||||||
opts.add_option("-t", "--temperature", type="string", dest="heater",
|
opts.add_option("-t", "--temperature", type="string", dest="heater",
|
||||||
default=None, help="graph heater temperature")
|
default=None, help="graph heater temperature")
|
||||||
opts.add_option("-m", "--mcu", type="string", dest="mcu", default=None,
|
opts.add_option("-m", "--mcu", type="string", dest="mcu", default=None,
|
||||||
help="limit stats to the given mcu")
|
help="limit stats to the given mcu")
|
||||||
options, args = opts.parse_args()
|
options, args = opts.parse_args()
|
||||||
if len(args) != 2:
|
if len(args) != 1:
|
||||||
opts.error("Incorrect number of arguments")
|
opts.error("Incorrect number of arguments")
|
||||||
logname, outname = args
|
logname = args[0]
|
||||||
|
|
||||||
|
# Parse data
|
||||||
data = parse_log(logname, options.mcu)
|
data = parse_log(logname, options.mcu)
|
||||||
if not data:
|
if not data:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Draw graph
|
||||||
|
setup_matplotlib(options.output is not None)
|
||||||
if options.heater is not None:
|
if options.heater is not None:
|
||||||
plot_temperature(data, outname, options.heater)
|
fig = plot_temperature(data, options.heater)
|
||||||
return
|
elif options.frequency:
|
||||||
if options.frequency:
|
fig = plot_frequency(data, options.mcu)
|
||||||
plot_frequency(data, outname, options.mcu)
|
else:
|
||||||
return
|
fig = plot_mcu(data, MAXBANDWIDTH)
|
||||||
plot_mcu(data, MAXBANDWIDTH, outname)
|
|
||||||
|
# Show graph
|
||||||
|
if options.output is None:
|
||||||
|
matplotlib.pyplot.show()
|
||||||
|
else:
|
||||||
|
fig.set_size_inches(8, 6)
|
||||||
|
fig.savefig(options.output)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue