mirror of
https://github.com/littlefs-project/littlefs.git
synced 2025-12-01 12:20:02 +00:00
scripts: plot[mpl].py: Adopted -s/--sort and -S for legend sorting
Before this, the only option for ordering the legend was by specifying
explicit -L/--add-label labels. This works for the most part, but
doesn't cover the case where you don't know the parameterization of the
input data.
And we already have -s/-S flags in other csv scripts, so it makes sense
to adopt them in plot.py/plotmpl.py to allow sorting by one or more
explicit fields.
Note that -s/-S can be combined with explicit -L/--add-labels to order
datasets with the same sort field:
$ ./scripts/plot.py bench.csv \
-bBLOCK_SIZE \
-xn \
-ybench_readed \
-ybench_proged \
-ybench_erased \
--legend \
-sBLOCK_SIZE \
-L'*,bench_readed=bs=%(BLOCK_SIZE)s' \
-L'*,bench_proged=' \
-L'*,bench_erased='
---
Unfortunately this conflicted with -s/--sleep, which is a common flag in
the ascii-art scripts. This was bound to conflict with -s/--sort
eventually, so a came up with some alternatives:
- -s/--sleep -> -~/--sleep
- -S/--coalesce -> -+/--coalesce
But I'll admit I'm not the happiest about these...
This commit is contained in:
@ -1711,7 +1711,7 @@ if __name__ == "__main__":
|
||||
action='store_true',
|
||||
help="Pipe directly to stdout.")
|
||||
parser.add_argument(
|
||||
'-s', '--sleep',
|
||||
'-~', '--sleep',
|
||||
type=float,
|
||||
help="Time in seconds to sleep between redraws when running "
|
||||
"with -k. Defaults to 2 seconds.")
|
||||
|
||||
@ -5161,7 +5161,7 @@ if __name__ == "__main__":
|
||||
action='store_true',
|
||||
help="Pipe directly to stdout.")
|
||||
parser.add_argument(
|
||||
'-s', '--sleep',
|
||||
'-~', '--sleep',
|
||||
type=float,
|
||||
help="Time in seconds to sleep between redraws when running "
|
||||
"with -k. Defaults to 2 seconds.")
|
||||
|
||||
@ -1845,11 +1845,11 @@ if __name__ == "__main__":
|
||||
action='store_true',
|
||||
help="Pipe directly to stdout.")
|
||||
parser.add_argument(
|
||||
'-S', '--coalesce',
|
||||
'-+', '--coalesce',
|
||||
type=lambda x: int(x, 0),
|
||||
help="Number of operations to coalesce together.")
|
||||
parser.add_argument(
|
||||
'-s', '--sleep',
|
||||
'-~', '--sleep',
|
||||
type=float,
|
||||
help="Seconds to sleep between draws, coalescing operations "
|
||||
"in between.")
|
||||
|
||||
@ -314,6 +314,19 @@ def dat(x, *args):
|
||||
else:
|
||||
raise
|
||||
|
||||
# a simple reverse-key class
|
||||
class Rev(co.namedtuple('Rev', 'a')):
|
||||
__slots__ = ()
|
||||
# yes we need all of these because we're a namedtuple
|
||||
def __lt__(self, other):
|
||||
return self.a > other.a
|
||||
def __gt__(self, other):
|
||||
return self.a < other.a
|
||||
def __le__(self, other):
|
||||
return self.a >= other.a
|
||||
def __ge__(self, other):
|
||||
return self.a <= other.a
|
||||
|
||||
def collect(csv_paths, defines=[]):
|
||||
# collect results from CSV files
|
||||
fields = []
|
||||
@ -1185,6 +1198,7 @@ def main_(ring, csv_paths, *,
|
||||
x=None,
|
||||
y=None,
|
||||
define=[],
|
||||
sort=None,
|
||||
labels=[],
|
||||
chars=[],
|
||||
line_chars=[],
|
||||
@ -1384,12 +1398,18 @@ def main_(ring, csv_paths, *,
|
||||
# note we don't need to filter by defines again
|
||||
datasets_, dataattrs_ = fold(results, all_by, all_x, all_y)
|
||||
|
||||
# order by labels
|
||||
# sort datasets
|
||||
datasets_ = co.OrderedDict(sorted(
|
||||
datasets_.items(),
|
||||
key=lambda kv: labels_.key(kv[0])))
|
||||
key=lambda kv: (
|
||||
# sort by explicit sort fields
|
||||
tuple((Rev if reverse else lambda x: x)(
|
||||
dat(dataattrs_[kv[0]].get(k,''), 0))
|
||||
for k, reverse in (sort or [])),
|
||||
# order by labels
|
||||
labels_.key(kv[0]))))
|
||||
|
||||
# and merge dataattrs
|
||||
# merge dataattrs
|
||||
mergedattrs_ = {k: v
|
||||
for dataattr in dataattrs_.values()
|
||||
for k, v in dataattr.items()}
|
||||
@ -1918,6 +1938,21 @@ if __name__ == "__main__":
|
||||
action='append',
|
||||
help="Only include results where this field is this value. May "
|
||||
"include comma-separated options and globs.")
|
||||
class AppendSort(argparse.Action):
|
||||
def __call__(self, parser, namespace, value, option):
|
||||
if namespace.sort is None:
|
||||
namespace.sort = []
|
||||
namespace.sort.append((value, option in {'-S', '--reverse-sort'}))
|
||||
parser.add_argument(
|
||||
'-s', '--sort',
|
||||
nargs='?',
|
||||
action=AppendSort,
|
||||
help="Sort by this field.")
|
||||
parser.add_argument(
|
||||
'-S', '--reverse-sort',
|
||||
nargs='?',
|
||||
action=AppendSort,
|
||||
help="Sort by this field, but backwards.")
|
||||
parser.add_argument(
|
||||
'-L', '--add-label',
|
||||
dest='labels',
|
||||
@ -2126,7 +2161,7 @@ if __name__ == "__main__":
|
||||
action='store_true',
|
||||
help="Pipe directly to stdout.")
|
||||
parser.add_argument(
|
||||
'-s', '--sleep',
|
||||
'-~', '--sleep',
|
||||
type=float,
|
||||
help="Time in seconds to sleep between redraws when running "
|
||||
"with -k. Defaults to 2 seconds.")
|
||||
|
||||
@ -198,6 +198,19 @@ def dat(x, *args):
|
||||
else:
|
||||
raise
|
||||
|
||||
# a simple reverse-key class
|
||||
class Rev(co.namedtuple('Rev', 'a')):
|
||||
__slots__ = ()
|
||||
# yes we need all of these because we're a namedtuple
|
||||
def __lt__(self, other):
|
||||
return self.a > other.a
|
||||
def __gt__(self, other):
|
||||
return self.a < other.a
|
||||
def __le__(self, other):
|
||||
return self.a >= other.a
|
||||
def __ge__(self, other):
|
||||
return self.a <= other.a
|
||||
|
||||
def collect(csv_paths, defines=[]):
|
||||
# collect results from CSV files
|
||||
fields = []
|
||||
@ -779,6 +792,7 @@ def main(csv_paths, output, *,
|
||||
x=None,
|
||||
y=None,
|
||||
define=[],
|
||||
sort=None,
|
||||
labels=[],
|
||||
colors=[],
|
||||
formats=[],
|
||||
@ -949,12 +963,18 @@ def main(csv_paths, output, *,
|
||||
# note we don't need to filter by defines again
|
||||
datasets_, dataattrs_ = fold(results, all_by, all_x, all_y)
|
||||
|
||||
# order by labels
|
||||
# sort datasets
|
||||
datasets_ = co.OrderedDict(sorted(
|
||||
datasets_.items(),
|
||||
key=lambda kv: labels_.key(kv[0])))
|
||||
key=lambda kv: (
|
||||
# sort by explicit sort fields
|
||||
tuple((Rev if reverse else lambda x: x)(
|
||||
dat(dataattrs_[kv[0]].get(k,''), 0))
|
||||
for k, reverse in (sort or [])),
|
||||
# order by labels
|
||||
labels_.key(kv[0]))))
|
||||
|
||||
# and merge dataattrs
|
||||
# merge dataattrs
|
||||
mergedattrs_ = {k: v
|
||||
for dataattr in dataattrs_.values()
|
||||
for k, v in dataattr.items()}
|
||||
@ -1372,6 +1392,21 @@ if __name__ == "__main__":
|
||||
action='append',
|
||||
help="Only include results where this field is this value. May "
|
||||
"include comma-separated options and globs.")
|
||||
class AppendSort(argparse.Action):
|
||||
def __call__(self, parser, namespace, value, option):
|
||||
if namespace.sort is None:
|
||||
namespace.sort = []
|
||||
namespace.sort.append((value, option in {'-S', '--reverse-sort'}))
|
||||
parser.add_argument(
|
||||
'-s', '--sort',
|
||||
nargs='?',
|
||||
action=AppendSort,
|
||||
help="Sort by this field.")
|
||||
parser.add_argument(
|
||||
'-S', '--reverse-sort',
|
||||
nargs='?',
|
||||
action=AppendSort,
|
||||
help="Sort by this field, but backwards.")
|
||||
parser.add_argument(
|
||||
'-L', '--add-label',
|
||||
dest='labels',
|
||||
|
||||
@ -236,11 +236,11 @@ if __name__ == "__main__":
|
||||
action='store_true',
|
||||
help="Pipe directly to stdout.")
|
||||
parser.add_argument(
|
||||
'-S', '--coalesce',
|
||||
'-+', '--coalesce',
|
||||
type=lambda x: int(x, 0),
|
||||
help="Number of lines to coalesce together.")
|
||||
parser.add_argument(
|
||||
'-s', '--sleep',
|
||||
'-~', '--sleep',
|
||||
type=float,
|
||||
help="Seconds to sleep between draws, coalescing lines in "
|
||||
"between.")
|
||||
|
||||
@ -1515,7 +1515,7 @@ if __name__ == "__main__":
|
||||
action='store_true',
|
||||
help="Pipe directly to stdout.")
|
||||
parser.add_argument(
|
||||
'-s', '--sleep',
|
||||
'-~', '--sleep',
|
||||
type=float,
|
||||
help="Time in seconds to sleep between redraws when running "
|
||||
"with -k. Defaults to 2 seconds.")
|
||||
|
||||
@ -329,7 +329,7 @@ if __name__ == "__main__":
|
||||
action='store_true',
|
||||
help="Pipe directly to stdout.")
|
||||
parser.add_argument(
|
||||
'-s', '--sleep',
|
||||
'-~', '--sleep',
|
||||
type=float,
|
||||
help="Seconds to sleep between runs. Defaults to 2 seconds.")
|
||||
parser.add_argument(
|
||||
|
||||
Reference in New Issue
Block a user