From 53562253b270acf430c3649dcf615f272058fc3f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 13 Jun 2017 21:25:59 -0400 Subject: [PATCH 1/9] cmake project file. --- CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..64a6b1f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.0) +project(madplotlib) + +include_directories(${CMAKE_CURRENT_LIST_DIR}) + +find_package(Qt5 REQUIRED COMPONENTS Charts) +include_directories(${Qt5_Charts_INCLUDE_DIRS}) + +find_package(Eigen3 REQUIRED) +include_directories(${Eigen3_INCLUDE_DIRS}) + +add_executable(eigen_test eigen_tests.cpp) +target_link_libraries(eigen_test Qt5::Charts) \ No newline at end of file From 4f4965a518efc47453420f9e55713c013f04619c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 14 Jun 2017 20:20:07 -0400 Subject: [PATCH 2/9] Initial implementation of named parameters. --- Madplotlib.h | 1278 ++++++++++------------------------------------- eigen_tests.cpp | 30 +- 2 files changed, 272 insertions(+), 1036 deletions(-) diff --git a/Madplotlib.h b/Madplotlib.h index 1e38120..0e59777 100644 --- a/Madplotlib.h +++ b/Madplotlib.h @@ -24,6 +24,208 @@ #include #include +#pragma once + +#define MO_KEYWORD_INPUT(name, type) \ +namespace tag{ \ + struct name { \ + typedef type Type; \ + typedef const Type& ConstRef; \ + typedef Type& Ref; \ + typedef ConstRef StorageType; \ + typedef const void* VoidType; \ + template \ + static constexpr bool AllowedType() { return std::is_same::value; } \ + static VoidType GetPtr(const Type& arg) { \ + return &arg; \ + } \ + template \ + static VoidType GetPtr(const T& arg) { \ + (void)arg; \ + return nullptr; \ + } \ + }; \ +} \ +static kwargs::TKeyword& _##name = kwargs::TKeyword::instance; + + +#define MO_KEYWORD_OUTPUT(name, type) \ +namespace tag{ \ + struct name { \ + typedef type Type; \ + typedef const Type& ConstRef; \ + typedef Type& Ref; \ + typedef Ref StorageType; \ + typedef void* VoidType; \ + template \ + static constexpr bool AllowedType() { return std::is_same::value; } \ + static VoidType GetPtr(Type& arg) { \ + return &arg; \ + } \ + template \ + static VoidType GetPtr(const T& arg) { \ + (void)arg; \ + return nullptr; \ + } \ + }; \ +} \ +static kwargs::TKeyword& _##name = kwargs::TKeyword::instance; + +namespace kwargs { + struct TaggedBase {}; + template + struct TaggedArgument : public TaggedBase { + typedef Tag TagType; + explicit TaggedArgument(typename Tag::StorageType val) + : arg(&val) { + } + + typename Tag::VoidType get() const { + return arg; + } + + protected: + typename Tag::VoidType arg; + }; + + template + struct TKeyword { + static TKeyword instance; + TaggedArgument operator=(typename Tag::StorageType data) { + return TaggedArgument(data); + } + }; + template + TKeyword TKeyword::instance; +} + +template +struct ArgType; + +template +struct ArgType<0, T0, T...> { + typedef T0 type; +}; +template +struct ArgType { + typedef typename ArgType::type type; +}; + +template +typename Tag::VoidType GetKeyImpl() { + return 0; +} + +template +constexpr int CountTypeImpl(const U& value) { + return std::is_same::value ? 1 : 0; +} + +template +constexpr int CountTypeImpl(const U& value, const Args&... args) { + return CountTypeImpl(args...) + (std::is_same::value ? 1 : 0); +} + +template +constexpr int CountType(const Args&... args) { + return CountTypeImpl(args...); +} + +template +auto GetPositionalInput(Args&&... as) noexcept -> decltype(std::get(std::forward_as_tuple(std::forward(as)...))) { + return std::get(std::forward_as_tuple(std::forward(as)...)); +} + +template +typename std::enable_if::value, typename Tag::VoidType>::type + GetKeyImpl(const T& arg, const Args&... args) { + return std::is_same::value ? const_cast(arg.get()) : const_cast(GetKeyImpl(args...)); +} + +template +typename std::enable_if::value, typename Tag::VoidType>::type + GetKeyImpl(const T& arg, const Args&... args) { +#ifdef __GNUC__ + //static_assert(CountType(arg, args...) <= 1, "Cannot infer type when there are multiple variadic Params with desired type"); +#endif + return Tag::template AllowedType() && Infer ? // This infers the type + Tag::GetPtr(arg) + : const_cast(GetKeyImpl(args...)); +} + +template +typename Tag::ConstRef GetKeywordInput(const Args&... args) { + const void* ptr = GetKeyImpl(args...); + assert(ptr); + return *(static_cast(ptr)); +} + +template +typename Tag::ConstRef GetKeywordInputDefault(typename Tag::ConstRef def, const Args&... args) { + const void* ptr = GetKeyImpl(args...); + if (ptr) + return *static_cast(ptr); + return def; +} + +template +const typename Tag::Type* GetKeywordInputOptional(const Args&... args) { + const void* ptr = GetKeyImpl(args...); + if (ptr) + return static_cast(ptr); + return nullptr; +} + +template +typename Tag::Ref GetKeywordOutput(const Args&... args) { + static_assert(!std::is_const::value, "Tag type is not an output tag"); + void* ptr = GetKeyImpl(args...); + assert(ptr); + return *(static_cast(ptr)); +} + +template +typename Tag::Type* GetKeywordOutputOptional(const Args&... args) { + static_assert(!std::is_const::value, "Tag type is not an output tag"); + void* ptr = GetKeyImpl(args...); + if (ptr) + return (static_cast(ptr)); + return nullptr; +} + +MO_KEYWORD_INPUT(x, Eigen::ArrayXf) +MO_KEYWORD_INPUT(y, Eigen::ArrayXf) +MO_KEYWORD_INPUT(marker, QString); +MO_KEYWORD_INPUT(label, QString); +MO_KEYWORD_INPUT(color, QColor); +MO_KEYWORD_INPUT(linewidth, quint32); +MO_KEYWORD_INPUT(alpha, qreal); +MO_KEYWORD_INPUT(edgecolor, QColor); +MO_KEYWORD_INPUT(markersize, qreal); + +template +struct is_matrix_expression : std::false_type {}; +template +struct is_matrix_expression() = std::declval(), void())> : std::true_type {}; + +template +constexpr bool detectExpressionArg(const Arg& arg) { + return is_matrix_expression::value; +} +template +constexpr bool detectExpressionArg(const Arg& arg, const Args&... args) { + return is_matrix_expression::value ? true : detectExpressionArg(args...); +} + +template typename std::enable_if::value>::type applyExpression(Eigen::ArrayXf& X, const Arg& Y) +{ + X = Y; +} + +template typename std::enable_if::value>::type applyExpression(Eigen::ArrayXf& X, const Arg& Y) +{ + +} /* Debug control */ @@ -60,6 +262,7 @@ class Madplotlib qDebug() << "Madplotlib(): isWidget=" << isWidget; #endif _chart = new QtCharts::QChart(); + _chartView = new QtCharts::QChartView(_chart); _enableGrid = false; @@ -310,1038 +513,71 @@ class Madplotlib return; } } - - /* Overloaded plot(y) methods with 1-2 parameters */ - - void plot(const Eigen::ArrayXf& y) - { - plot(y, DEFAULT_MARKER, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const qreal& alpha) - { - plot(y, DEFAULT_MARKER, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QColor& color) - { - plot(y, DEFAULT_MARKER, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const quint32& linewidth) - { - plot(y, DEFAULT_MARKER, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - /* Overloaded plot(y) methods with 3 parameters */ - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const quint32& linewidth) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const qreal& alpha, const QColor& color) - { - plot(y, DEFAULT_MARKER, DEFAULT_LEGEND, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const qreal& alpha, const quint32& linewidth) - { - plot(y, DEFAULT_MARKER, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const qreal& alpha, const qreal& markersize) - { - plot(y, DEFAULT_MARKER, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QColor& color, const quint32& linewidth) - { - plot(y, DEFAULT_MARKER, DEFAULT_LEGEND, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QColor& color, const qreal& markersize) - { - plot(y, DEFAULT_MARKER, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - /* Overloaded plot(y) methods with 4 parameters */ - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const quint32& linewidth) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const quint32& linewidth) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const QColor& edgecolor) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const quint32& linewidth) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const quint32& linewidth, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const quint32& linewidth, const QColor& edgecolor) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const qreal& alpha, const QColor& color, const quint32& linewidth) - { - plot(y, DEFAULT_MARKER, DEFAULT_LEGEND, alpha, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - /* Overloaded plot(y) methods with 5 parameters */ - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const quint32& linewidth) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(y, cmd2, cmd1, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const QColor& edgecolor) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const quint32& linewidth) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const quint32& linewidth, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const quint32& linewidth, const QColor& edgecolor) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const QColor& edgecolor) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const quint32& linewidth) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const quint32& linewidth, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const quint32& linewidth, const QColor& edgecolor) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const QColor& edgecolor, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const quint32& linewidth, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - /* Overloaded plot(y) methods with 6 parameters */ - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const QColor& edgecolor) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, alpha, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const quint32& linewidth) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, alpha, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const qreal& markersize) + + template + typename std::enable_if::value>::type plot(const Eigen::ArrayXf& y, const T& arg1, const Args&... args) { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(y, cmd2, cmd1, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } +#if (DEBUG > 0) && (DEBUG < 2) + qDebug() << "plot(y): marker=" << marker << " alpha=" << alpha << + " color=" << color << " edgecolor=" << edgecolor << + " linewidth=" << linewidth << " markersize=" << markersize; +#endif + if (y.rows() == 0) + { + qCritical() << "plot(y): axis size must be > 0 but its " << y.rows(); + exit(-1); + } - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const quint32& linewidth, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); + // number of x values needed to accompany the y values + int num_items = y.rows(); - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(y, cmd2, cmd1, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - } + // make up X data and plot into series, but take into account that xlim() + // could have been called with the start and end of x series. + Eigen::ArrayXf x = Eigen::ArrayXf(y.rows()); + qreal x_inc = 1; + if (_customLimits && (_xMin != _xMax)) + { + qreal xrange = _xMax - _xMin; + x_inc = xrange / y.rows(); + } - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const quint32& linewidth, const QColor& edgecolor) - { - _check_cmds_are_good(cmd1, cmd2); + qreal x_value = _xMin; + for (int i = 0; i < num_items; i++) + { + x[i] = x_value; + x_value += x_inc; - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, color, linewidth, edgecolor, DEFAULT_MARKERSZ); +#if (DEBUG > 1) && (DEBUG < 3) + qDebug() << "plot(y): generated x[" << i << "]=" << x[i]; +#endif + } + plot(x, y, arg1, args...); } - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const QColor& edgecolor, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, markersize); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, markersize); - } + /* plot(): called when user needs to put data on a chart. + * x: an array that stores x axis values. + * y: an array that stores y axis values. + * marker: chart types. "-" for line plot and "o" for scatter plot. + * alpha: defines the transparency level of the color. + * color: defines the color used to draw the data. + * edgecolor: defines the edge color of "o" marker. + * linewidth: defines the width of the pen used to draw "-" marker. + * markersize: defines the size of "o" marker. + */ - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const quint32& linewidth, const qreal& markersize) + template + typename std::enable_if::value>::type plot(const Eigen::ArrayXf& x, const T& y, const Args&... args) { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(y, cmd2, cmd1, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, markersize); - } + const QString marker = GetKeywordInputDefault(DEFAULT_MARKER, args...); + const QString label = GetKeywordInputDefault(DEFAULT_LEGEND, args...); + const qreal& alpha = GetKeywordInputDefault(DEFAULT_ALPHA, args...); + const QColor color = GetKeywordInputDefault(DEFAULT_COLOR, args...); + const quint32& linewidth = GetKeywordInputDefault(DEFAULT_LINEW, args...); + const QColor edgecolor = GetKeywordInputDefault(DEFAULT_EDGECOLOR, args...); + const qreal& markersize = GetKeywordInputDefault(DEFAULT_MARKERSZ, args...); - void plot(const Eigen::ArrayXf& y, const QString& cmd1,const qreal& alpha, const QColor& color, const quint32& linewidth, const QColor& edgecolor) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const QColor& edgecolor, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, color, DEFAULT_LINEW, edgecolor, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, color, DEFAULT_LINEW, edgecolor, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const quint32& linewidth, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, color, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, color, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const quint32& linewidth, const QColor& edgecolor, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, linewidth, edgecolor, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, linewidth, edgecolor, markersize); - } - - /* Overloaded plot(y) methods with 7 parameters */ - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const quint32& linewidth, const QColor& edgecolor) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(y, cmd2, cmd1, alpha, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const QColor& edgecolor, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, color, DEFAULT_LINEW, edgecolor, markersize); - else - plot(y, cmd2, cmd1, alpha, color, DEFAULT_LINEW, edgecolor, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const quint32& linewidth, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, cmd2, alpha, color, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(y, cmd2, cmd1, alpha, color, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const quint32& linewidth, const QColor& edgecolor, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, linewidth, edgecolor, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, linewidth, edgecolor, markersize); - } - - void plot(const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const quint32& linewidth, const QColor& edgecolor, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(y, cmd1, DEFAULT_LEGEND, alpha, color, linewidth, edgecolor, markersize); - else - plot(y, DEFAULT_MARKER, cmd1, alpha, color, linewidth, edgecolor, markersize); - } - - /* Overloaded plot(x,y) methods with 2-3 parameters */ - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y) - { - plot(x, y, DEFAULT_MARKER, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const qreal& alpha) - { - plot(x, y, DEFAULT_MARKER, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QColor& color) - { - plot(x, y, DEFAULT_MARKER, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const quint32& linewidth) - { - plot(x, y, DEFAULT_MARKER, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - /* Overloaded plot(x,y) methods with 4 parameters */ - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const quint32& linewidth) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const qreal& alpha, const QColor& color) - { - plot(x, y, DEFAULT_MARKER, DEFAULT_LEGEND, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const qreal& alpha, const quint32& linewidth) - { - plot(x, y, DEFAULT_MARKER, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const qreal& alpha, const qreal& markersize) - { - plot(x, y, DEFAULT_MARKER, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QColor& color, const quint32& linewidth) - { - plot(x, y, DEFAULT_MARKER, DEFAULT_LEGEND, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QColor& color, const qreal& markersize) - { - plot(x, y, DEFAULT_MARKER, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - /* Overloaded plot(x,y) methods with 5 parameters */ - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const quint32& linewidth) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const quint32& linewidth) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const QColor& edgecolor) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const quint32& linewidth) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const quint32& linewidth, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const quint32& linewidth, const QColor& edgecolor) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const qreal& alpha, const QColor& color, const quint32& linewidth) - { - plot(x, y, DEFAULT_MARKER, DEFAULT_LEGEND, alpha, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - /* Overloaded plot(x,y) methods with 6 parameters */ - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const quint32& linewidth) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, cmd2, cmd1, alpha, DEFAULT_COLOR, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const QColor& edgecolor) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const quint32& linewidth) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const quint32& linewidth, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const quint32& linewidth, const QColor& edgecolor) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const QColor& edgecolor) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const quint32& linewidth) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const quint32& linewidth, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const quint32& linewidth, const QColor& edgecolor) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, DEFAULT_COLOR, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const QColor& edgecolor, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const quint32& linewidth, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - /* Overloaded plot(x,y) methods with 7 parameters */ - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const QColor& edgecolor) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, alpha, color, DEFAULT_LINEW, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const quint32& linewidth) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, alpha, color, linewidth, DEFAULT_EDGECOLOR, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, cmd2, cmd1, alpha, color, DEFAULT_LINEW, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const quint32& linewidth, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, cmd2, cmd1, alpha, DEFAULT_COLOR, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const quint32& linewidth, const QColor& edgecolor) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const QColor& edgecolor, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, markersize); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, color, DEFAULT_LINEW, edgecolor, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const quint32& linewidth, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, cmd2, cmd1, DEFAULT_ALPHA, color, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1,const qreal& alpha, const QColor& color, const quint32& linewidth, const QColor& edgecolor) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const QColor& edgecolor, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, color, DEFAULT_LINEW, edgecolor, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, color, DEFAULT_LINEW, edgecolor, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const quint32& linewidth, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, color, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, color, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QColor& color, const quint32& linewidth, const QColor& edgecolor, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, linewidth, edgecolor, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, linewidth, edgecolor, markersize); - } - - /* Overloaded plot(x,y) methods with 8 parameters */ - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const quint32& linewidth, const QColor& edgecolor) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - else - plot(x, y, cmd2, cmd1, alpha, color, linewidth, edgecolor, DEFAULT_MARKERSZ); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const QColor& edgecolor, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, color, DEFAULT_LINEW, edgecolor, markersize); - else - plot(x, y, cmd2, cmd1, alpha, color, DEFAULT_LINEW, edgecolor, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const qreal& alpha, const QColor& color, const quint32& linewidth, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, cmd2, alpha, color, linewidth, DEFAULT_EDGECOLOR, markersize); - else - plot(x, y, cmd2, cmd1, alpha, color, linewidth, DEFAULT_EDGECOLOR, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const QString& cmd2, const QColor& color, const quint32& linewidth, const QColor& edgecolor, const qreal& markersize) - { - _check_cmds_are_good(cmd1, cmd2); - - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, DEFAULT_ALPHA, color, linewidth, edgecolor, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, DEFAULT_ALPHA, color, linewidth, edgecolor, markersize); - } - - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const QString& cmd1, const qreal& alpha, const QColor& color, const quint32& linewidth, const QColor& edgecolor, const qreal& markersize) - { - if (_is_marker(cmd1)) - plot(x, y, cmd1, DEFAULT_LEGEND, alpha, color, linewidth, edgecolor, markersize); - else - plot(x, y, DEFAULT_MARKER, cmd1, alpha, color, linewidth, edgecolor, markersize); - } - - /* plot(y): this implementation handles calls that do not specify X data. - * For that purpose, this method fabricates the data needed to plot Y series - * correctly on the chart. - */ - void plot(const Eigen::ArrayXf& y, const QString& marker, const QString& label, - const qreal& alpha, const QColor& color, const quint32& linewidth, - const QColor& edgecolor, const qreal& markersize) - { -#if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "plot(y): marker=" << marker << " alpha=" << alpha << - " color=" << color << " edgecolor=" << edgecolor << - " linewidth=" << linewidth << " markersize=" << markersize; -#endif - if (y.rows() == 0) - { - qCritical() << "plot(y): axis size must be > 0 but its " << y.rows(); - exit(-1); - } - - // number of x values needed to accompany the y values - int num_items = y.rows(); - - // make up X data and plot into series, but take into account that xlim() - // could have been called with the start and end of x series. - Eigen::ArrayXf x = Eigen::ArrayXf(y.rows()); - qreal x_inc = 1; - if (_customLimits && (_xMin != _xMax)) - { - qreal xrange = _xMax - _xMin; - x_inc = xrange / y.rows(); - } - - qreal x_value = _xMin; - for (int i = 0; i < num_items; i++) - { - x[i] = x_value; - x_value += x_inc; - -#if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(y): generated x[" << i << "]=" << x[i]; -#endif - } - - plot(x, y, marker, label, alpha, color, linewidth, edgecolor, markersize); - } - - /* plot(): called when user needs to put data on a chart. - * x: an array that stores x axis values. - * y: an array that stores y axis values. - * marker: chart types. "-" for line plot and "o" for scatter plot. - * alpha: defines the transparency level of the color. - * color: defines the color used to draw the data. - * edgecolor: defines the edge color of "o" marker. - * linewidth: defines the width of the pen used to draw "-" marker. - * markersize: defines the size of "o" marker. - */ - void plot(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, - const QString& marker, const QString& label, - const qreal& alpha, const QColor& color, const quint32& linewidth, - const QColor& edgecolor, const qreal& markersize) - { + #if (DEBUG > 0) && (DEBUG < 2) qDebug() << "plot(x,y): marker:" << marker << " alpha:" << alpha << " color:" << color << " edgecolor:" << edgecolor << diff --git a/eigen_tests.cpp b/eigen_tests.cpp index bce5333..a91c901 100644 --- a/eigen_tests.cpp +++ b/eigen_tests.cpp @@ -84,9 +84,9 @@ void test3() Madplotlib plt; plt.title("Test 3: Multiple Data Series"); plt.axis(0, 25, 0, 14); - plt.plot(x, y, QString("--"), QString("label=Dashed Line")); - plt.plot(x, y+5, QString("label=Default Line"), (quint32)4); - plt.plot(x, y+10, QString("."), QString("label=Dotted Line")); + plt.plot(x, y, _marker=QString("--"), _label=QString("label=Dashed Line")); + plt.plot(x, y+5, _label=QString("label=Default Line"), (quint32)4); + plt.plot(x, y+10, QString("."), _label=QString("label=Dotted Line")); plt.legend(); // default position is "lower center" plt.show(); @@ -125,8 +125,8 @@ void test4() plt.title("Test 4: Random Scatter Plot"); plt.locator_params("x", 10); plt.axis(-25, 100, -25, 100); - plt.plot(x, y, QString("o"), 0.7f, QColor(255, 0, 0), 8.0f); // red, 30% transparent, markersize 8 - plt.plot(x2, y2, QString("o"), 0.5f, QColor(0, 0, 255)); // blue, 50% transparent + plt.plot(x, y, _marker=QString("o"), 0.7f, QColor(255, 0, 0), 8.0f); // red, 30% transparent, markersize 8 + plt.plot(x2, y2, _marker=QString("o"), 0.5f, QColor(0, 0, 255)); // blue, 50% transparent plt.show(); #ifdef SCRSHOT @@ -191,10 +191,10 @@ void test6() 105, 111, 120, 126, 120, 104, 85, 92; Madplotlib plt; - plt.plot(x, y, QColor(0xFF2700)); // red - plt.plot(x, y, QString("o"), QColor(0xFF2700)); - plt.plot(x, y-40, QColor(0x008FD5)); // blue - plt.plot(x, y-40, QString("o"), QColor(0x008FD5)); + plt.plot(x, y, _color=QColor(0xFF2700)); // red + plt.plot(x, y, _marker=QString("o"), _color=QColor(0xFF2700)); + plt.plot(x, y-40, _color=QColor(0x008FD5)); // blue + plt.plot(x, y-40, _marker=QString("o"), _color=QColor(0x008FD5)); plt.title("Test 6: Line + Scatter"); plt.xlabel("X values"); @@ -240,7 +240,7 @@ void test7() // On Qt 7.5, Qt Charts has a bug spacing correctly categories on negative Y axis (-1, 1). // For now, drawing (y+1) will bypass that since the values will fall between (0, 2). plt.ylim(0, 2); - plt.plot(x, y+1, QString("o"), 1.f, 2, 7.0f); // alpha=1.f, linewidth=2, markersize=7.f + plt.plot(x, y+1, _marker=QString("o"), _alpha=1.f, _linewidth=2, _markersize=7.0f); // alpha=1.f, linewidth=2, markersize=7.f plt.grid(true); plt.show(); @@ -265,13 +265,13 @@ void test8() Madplotlib plt; plt.title("Test 8: Line + Square Markers + Hidden Ticks"); plt.axis("off"); - plt.plot(x, x.sqrt(), QColor(0, 0, 0)); - plt.plot(x, -x.sqrt(), QColor(0, 0, 0)); + plt.plot(x, x.sqrt(), _color=QColor(0, 0, 0)); + plt.plot(x, -x.sqrt(), _color = QColor(0, 0, 0)); Eigen::ArrayXf noise = Eigen::ArrayXf::Random(50) * 2; - plt.plot(x, x.sqrt() - noise, QString("s"), 0.7f, QColor(19, 154, 255), QColor(19, 154, 255)); // red squares without black edges - plt.plot(x, -x.sqrt() - noise, QString("s"), 0.7f, QColor(255, 41, 5), QColor(255, 41, 5)); // blue squares without black edges + plt.plot(x, x.sqrt() - noise, _marker=QString("s"), _markersize = 0.7f, _color=QColor(19, 154, 255), _edgecolor=QColor(19, 154, 255)); // red squares without black edges + plt.plot(x, -x.sqrt() - noise, _marker = QString("s"), _markersize = 0.7f, _color=QColor(255, 41, 5), _edgecolor=QColor(255, 41, 5)); // blue squares without black edges plt.show(); #ifdef SCRSHOT @@ -345,7 +345,7 @@ void test10() // On Qt 7.5, Qt Charts has a bug spacing correctly categories on negative X axis (-3.1, 3.1). // For now, make sure you are using only positive X values to bypass that problem. plt.plot(X, C); - plt.plot(X, S, QString("--")); + plt.plot(X, S, _marker=QString("--")); plt.xlim(0, 2*pi); plt.xticks(x_ticks, x_labels); plt.show(); From 54ca5f119cc29aecd1c5517daf6fb6d05699d37d Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 16 Jun 2017 18:36:23 -0400 Subject: [PATCH 3/9] remove _ prefix for all named arguments. added a define which can be used to place them in a separate namespace if the user doesn't want them in the global namespace. removed the requirement for constexpr. --- Madplotlib.h | 47 +++++++++++++++++++++++------------------------ eigen_tests.cpp | 30 +++++++++++++++--------------- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/Madplotlib.h b/Madplotlib.h index 0e59777..4f35c6f 100644 --- a/Madplotlib.h +++ b/Madplotlib.h @@ -26,6 +26,20 @@ #pragma once +#ifndef PLT_ARG_NAMESPACE +#define PLT_ARG_NAMESPACE +#endif + +#ifdef _MSC_VER +#if _MSC_VER >= 1900 +#define PLT_CONSTEXPR constexpr +#else +#define PLT_CONSTEXPR +#endif +#else +#define PLT_CONSTEXPR constexpr +#endif + #define MO_KEYWORD_INPUT(name, type) \ namespace tag{ \ struct name { \ @@ -46,7 +60,9 @@ namespace tag{ } \ }; \ } \ -static kwargs::TKeyword& _##name = kwargs::TKeyword::instance; +namespace PLT_ARG_NAMESPACE { \ + static kwargs::TKeyword& name = kwargs::TKeyword::instance; \ +} #define MO_KEYWORD_OUTPUT(name, type) \ @@ -69,7 +85,9 @@ namespace tag{ } \ }; \ } \ -static kwargs::TKeyword& _##name = kwargs::TKeyword::instance; +namespace PLT_ARG_NAMESPACE { \ +static kwargs::TKeyword& name = kwargs::TKeyword::instance; \ +} namespace kwargs { struct TaggedBase {}; @@ -117,17 +135,17 @@ typename Tag::VoidType GetKeyImpl() { } template -constexpr int CountTypeImpl(const U& value) { +PLT_CONSTEXPR int CountTypeImpl(const U& value) { return std::is_same::value ? 1 : 0; } template -constexpr int CountTypeImpl(const U& value, const Args&... args) { +PLT_CONSTEXPR int CountTypeImpl(const U& value, const Args&... args) { return CountTypeImpl(args...) + (std::is_same::value ? 1 : 0); } template -constexpr int CountType(const Args&... args) { +PLT_CONSTEXPR int CountType(const Args&... args) { return CountTypeImpl(args...); } @@ -208,25 +226,6 @@ struct is_matrix_expression : std::false_type {}; template struct is_matrix_expression() = std::declval(), void())> : std::true_type {}; -template -constexpr bool detectExpressionArg(const Arg& arg) { - return is_matrix_expression::value; -} -template -constexpr bool detectExpressionArg(const Arg& arg, const Args&... args) { - return is_matrix_expression::value ? true : detectExpressionArg(args...); -} - -template typename std::enable_if::value>::type applyExpression(Eigen::ArrayXf& X, const Arg& Y) -{ - X = Y; -} - -template typename std::enable_if::value>::type applyExpression(Eigen::ArrayXf& X, const Arg& Y) -{ - -} - /* Debug control */ #define DEBUG 0 // level 0: debug msgs are disabled diff --git a/eigen_tests.cpp b/eigen_tests.cpp index a91c901..570eea0 100644 --- a/eigen_tests.cpp +++ b/eigen_tests.cpp @@ -84,9 +84,9 @@ void test3() Madplotlib plt; plt.title("Test 3: Multiple Data Series"); plt.axis(0, 25, 0, 14); - plt.plot(x, y, _marker=QString("--"), _label=QString("label=Dashed Line")); - plt.plot(x, y+5, _label=QString("label=Default Line"), (quint32)4); - plt.plot(x, y+10, QString("."), _label=QString("label=Dotted Line")); + plt.plot(x, y, marker=QString("--"), label=QString("label=Dashed Line")); + plt.plot(x, y+5, label=QString("label=Default Line"), (quint32)4); + plt.plot(x, y+10, QString("."), label=QString("label=Dotted Line")); plt.legend(); // default position is "lower center" plt.show(); @@ -125,8 +125,8 @@ void test4() plt.title("Test 4: Random Scatter Plot"); plt.locator_params("x", 10); plt.axis(-25, 100, -25, 100); - plt.plot(x, y, _marker=QString("o"), 0.7f, QColor(255, 0, 0), 8.0f); // red, 30% transparent, markersize 8 - plt.plot(x2, y2, _marker=QString("o"), 0.5f, QColor(0, 0, 255)); // blue, 50% transparent + plt.plot(x, y, marker=QString("o"), 0.7f, QColor(255, 0, 0), 8.0f); // red, 30% transparent, markersize 8 + plt.plot(x2, y2, marker=QString("o"), 0.5f, QColor(0, 0, 255)); // blue, 50% transparent plt.show(); #ifdef SCRSHOT @@ -191,10 +191,10 @@ void test6() 105, 111, 120, 126, 120, 104, 85, 92; Madplotlib plt; - plt.plot(x, y, _color=QColor(0xFF2700)); // red - plt.plot(x, y, _marker=QString("o"), _color=QColor(0xFF2700)); - plt.plot(x, y-40, _color=QColor(0x008FD5)); // blue - plt.plot(x, y-40, _marker=QString("o"), _color=QColor(0x008FD5)); + plt.plot(x, y, color=QColor(0xFF2700)); // red + plt.plot(x, y, marker=QString("o"), color=QColor(0xFF2700)); + plt.plot(x, y-40, color=QColor(0x008FD5)); // blue + plt.plot(x, y-40, marker=QString("o"), color=QColor(0x008FD5)); plt.title("Test 6: Line + Scatter"); plt.xlabel("X values"); @@ -240,7 +240,7 @@ void test7() // On Qt 7.5, Qt Charts has a bug spacing correctly categories on negative Y axis (-1, 1). // For now, drawing (y+1) will bypass that since the values will fall between (0, 2). plt.ylim(0, 2); - plt.plot(x, y+1, _marker=QString("o"), _alpha=1.f, _linewidth=2, _markersize=7.0f); // alpha=1.f, linewidth=2, markersize=7.f + plt.plot(x, y+1, marker=QString("o"), alpha=1.f, linewidth=2, markersize=7.0f); // alpha=1.f, linewidth=2, markersize=7.f plt.grid(true); plt.show(); @@ -265,13 +265,13 @@ void test8() Madplotlib plt; plt.title("Test 8: Line + Square Markers + Hidden Ticks"); plt.axis("off"); - plt.plot(x, x.sqrt(), _color=QColor(0, 0, 0)); - plt.plot(x, -x.sqrt(), _color = QColor(0, 0, 0)); + plt.plot(x, x.sqrt(), color=QColor(0, 0, 0)); + plt.plot(x, -x.sqrt(), color = QColor(0, 0, 0)); Eigen::ArrayXf noise = Eigen::ArrayXf::Random(50) * 2; - plt.plot(x, x.sqrt() - noise, _marker=QString("s"), _markersize = 0.7f, _color=QColor(19, 154, 255), _edgecolor=QColor(19, 154, 255)); // red squares without black edges - plt.plot(x, -x.sqrt() - noise, _marker = QString("s"), _markersize = 0.7f, _color=QColor(255, 41, 5), _edgecolor=QColor(255, 41, 5)); // blue squares without black edges + plt.plot(x, x.sqrt() - noise, marker=QString("s"), markersize = 0.7f, color=QColor(19, 154, 255), edgecolor=QColor(19, 154, 255)); // red squares without black edges + plt.plot(x, -x.sqrt() - noise, marker = QString("s"), markersize = 0.7f, color=QColor(255, 41, 5), edgecolor=QColor(255, 41, 5)); // blue squares without black edges plt.show(); #ifdef SCRSHOT @@ -345,7 +345,7 @@ void test10() // On Qt 7.5, Qt Charts has a bug spacing correctly categories on negative X axis (-3.1, 3.1). // For now, make sure you are using only positive X values to bypass that problem. plt.plot(X, C); - plt.plot(X, S, _marker=QString("--")); + plt.plot(X, S, marker=QString("--")); plt.xlim(0, 2*pi); plt.xticks(x_ticks, x_labels); plt.show(); From 5f9256d37361251ac07d35fadce78340f3a6729b Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 16 Jun 2017 18:57:44 -0400 Subject: [PATCH 4/9] fixed test8 --- eigen_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eigen_tests.cpp b/eigen_tests.cpp index 570eea0..9d14ee8 100644 --- a/eigen_tests.cpp +++ b/eigen_tests.cpp @@ -270,8 +270,8 @@ void test8() Eigen::ArrayXf noise = Eigen::ArrayXf::Random(50) * 2; - plt.plot(x, x.sqrt() - noise, marker=QString("s"), markersize = 0.7f, color=QColor(19, 154, 255), edgecolor=QColor(19, 154, 255)); // red squares without black edges - plt.plot(x, -x.sqrt() - noise, marker = QString("s"), markersize = 0.7f, color=QColor(255, 41, 5), edgecolor=QColor(255, 41, 5)); // blue squares without black edges + plt.plot(x, x.sqrt() - noise, marker=QString("s"), alpha = 0.7f, color=QColor(19, 154, 255), edgecolor=QColor(19, 154, 255)); // red squares without black edges + plt.plot(x, -x.sqrt() - noise, marker = QString("s"), alpha = 0.7f, color=QColor(255, 41, 5), edgecolor=QColor(255, 41, 5)); // blue squares without black edges plt.show(); #ifdef SCRSHOT From 98646404b1d2779bcd2544b5e07a202aa8f97108 Mon Sep 17 00:00:00 2001 From: dan Date: Sun, 18 Jun 2017 17:26:03 -0400 Subject: [PATCH 5/9] Fixed msvc2013! --- Madplotlib.h | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/Madplotlib.h b/Madplotlib.h index 4f35c6f..6d1a5e8 100644 --- a/Madplotlib.h +++ b/Madplotlib.h @@ -49,7 +49,7 @@ namespace tag{ typedef ConstRef StorageType; \ typedef const void* VoidType; \ template \ - static constexpr bool AllowedType() { return std::is_same::value; } \ + static PLT_CONSTEXPR bool AllowedType() { return std::is_same::value; } \ static VoidType GetPtr(const Type& arg) { \ return &arg; \ } \ @@ -74,7 +74,7 @@ namespace tag{ typedef Ref StorageType; \ typedef void* VoidType; \ template \ - static constexpr bool AllowedType() { return std::is_same::value; } \ + static PLT_CONSTEXPR bool AllowedType() { return std::is_same::value; } \ static VoidType GetPtr(Type& arg) { \ return &arg; \ } \ @@ -150,7 +150,7 @@ PLT_CONSTEXPR int CountType(const Args&... args) { } template -auto GetPositionalInput(Args&&... as) noexcept -> decltype(std::get(std::forward_as_tuple(std::forward(as)...))) { +auto GetPositionalInput(Args&&... as) -> decltype(std::get(std::forward_as_tuple(std::forward(as)...))) { return std::get(std::forward_as_tuple(std::forward(as)...)); } @@ -213,18 +213,27 @@ typename Tag::Type* GetKeywordOutputOptional(const Args&... args) { MO_KEYWORD_INPUT(x, Eigen::ArrayXf) MO_KEYWORD_INPUT(y, Eigen::ArrayXf) -MO_KEYWORD_INPUT(marker, QString); -MO_KEYWORD_INPUT(label, QString); -MO_KEYWORD_INPUT(color, QColor); -MO_KEYWORD_INPUT(linewidth, quint32); -MO_KEYWORD_INPUT(alpha, qreal); -MO_KEYWORD_INPUT(edgecolor, QColor); -MO_KEYWORD_INPUT(markersize, qreal); - -template +MO_KEYWORD_INPUT(marker, QString) +MO_KEYWORD_INPUT(label, QString) +MO_KEYWORD_INPUT(color, QColor) +MO_KEYWORD_INPUT(linewidth, quint32) +MO_KEYWORD_INPUT(alpha, qreal) +MO_KEYWORD_INPUT(edgecolor, QColor) +MO_KEYWORD_INPUT(markersize, qreal) + +// The below works on MSVC 2015 +/*template struct is_matrix_expression : std::false_type {}; template -struct is_matrix_expression() = std::declval(), void())> : std::true_type {}; +struct is_matrix_expression() = std::declval(), void())> : std::true_type {};*/ + +// Not sure if there are limitations to this but it seems to work on 2013 +template +struct is_matrix_expression + : std::is_base_of >, std::decay_t > +{}; + + /* Debug control */ @@ -550,7 +559,7 @@ class Madplotlib qDebug() << "plot(y): generated x[" << i << "]=" << x[i]; #endif } - plot(x, y, arg1, args...); + plotXY(x, y, arg1, args...); } @@ -564,9 +573,14 @@ class Madplotlib * linewidth: defines the width of the pen used to draw "-" marker. * markersize: defines the size of "o" marker. */ - - template - typename std::enable_if::value>::type plot(const Eigen::ArrayXf& x, const T& y, const Args&... args) + template + typename std::enable_if::value>::type plot(const Eigen::ArrayXf& x, const T& y, const Args&... args) + { + plotXY(x, y, args...); + } + + template + void plotXY(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const Args&... args) { const QString marker = GetKeywordInputDefault(DEFAULT_MARKER, args...); const QString label = GetKeywordInputDefault(DEFAULT_LEGEND, args...); From 08c863f232bc59ea9d48942b123a88be57a2f418 Mon Sep 17 00:00:00 2001 From: dan Date: Sun, 2 Jul 2017 00:56:29 -0400 Subject: [PATCH 6/9] improved plotting performance when repeatedly updating plot. --- Madplotlib.h | 149 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 54 deletions(-) diff --git a/Madplotlib.h b/Madplotlib.h index 6d1a5e8..708f486 100644 --- a/Madplotlib.h +++ b/Madplotlib.h @@ -269,6 +269,7 @@ class Madplotlib #if (DEBUG > 0) && (DEBUG < 2) qDebug() << "Madplotlib(): isWidget=" << isWidget; #endif + _xAxisTop = _xAxisBottom = _yAxisLeft = _yAxisRight = nullptr; _chart = new QtCharts::QChart(); _chartView = new QtCharts::QChartView(_chart); @@ -432,6 +433,9 @@ class Madplotlib #endif if (!_pixmap.isNull()) _pixmap.save(filename); + else if(_isWidget && _chartView){ + _pixmap = _chartView->grab(); + } } /* xticks(): sets the x-limits of the current tick locations and labels. @@ -640,31 +644,37 @@ class Madplotlib "] yrange [" << _yMin << "," << _yMax << "]"; #endif - QtCharts::QXYSeries* series = NULL; - if (marker == "o" || marker == "s") // it's a scatter plot! - { -#if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(x,y): scatter plot"; -#endif - QtCharts::QScatterSeries* s = new QtCharts::QScatterSeries(); - s->setMarkerSize(markersize); // symbol size - - if (marker == "o") - s->setMarkerShape(QtCharts::QScatterSeries::MarkerShapeCircle); - - if (marker == "s") - s->setMarkerShape(QtCharts::QScatterSeries::MarkerShapeRectangle); - - series = (QtCharts::QXYSeries*)s; - } - else // draw line - { -#if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(x,y): line plot"; -#endif - series = new QtCharts::QLineSeries(); + std::shared_ptr series; + auto itr = _seriesVec.find(_legend); + if(itr != _seriesVec.end()){ + series = *itr; + }else{ + if (marker == "o" || marker == "s") // it's a scatter plot! + { + #if (DEBUG > 1) && (DEBUG < 3) + qDebug() << "plot(x,y): scatter plot"; + #endif + QtCharts::QScatterSeries* s = new QtCharts::QScatterSeries(); + s->setMarkerSize(markersize); // symbol size + + if (marker == "o") + s->setMarkerShape(QtCharts::QScatterSeries::MarkerShapeCircle); + + if (marker == "s") + s->setMarkerShape(QtCharts::QScatterSeries::MarkerShapeRectangle); + + series.reset((QtCharts::QXYSeries*)s); + series->setUseOpenGL(true); + } + else // draw line + { + #if (DEBUG > 1) && (DEBUG < 3) + qDebug() << "plot(x,y): line plot"; + #endif + series.reset(new QtCharts::QLineSeries()); + series->setUseOpenGL(true); + } } - // Call a string parser! Ex: "label=Trump Tweets" becomes "Trump Tweets" _parseLegend(); if (_legend.size()) @@ -674,13 +684,19 @@ class Madplotlib #endif series->setName(_legend); } - - for (int i = 0; i < x.rows(); i++) - { + + if(series->count() == x.rows()){ + for (int i = 0; i < x.rows(); i++) + series->replace(i, x[i], y[i]); + }else{ + series->clear(); + for (int i = 0; i < x.rows(); i++) + { #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(x,y): x[" << i << "]=" << x[i] << " y[" << i << "]=" << y[i]; + qDebug() << "plot(x,y): x[" << i << "]=" << x[i] << " y[" << i << "]=" << y[i]; #endif - series->append(x[i], y[i]); + series->append(x[i], y[i]); + } } // Customize series color and transparency @@ -732,7 +748,8 @@ class Madplotlib if (_colorIdx >= _colors.size()) _colorIdx = 0; - _seriesVec.push_back(series); + //_seriesVec.push_back(series); + _seriesVec[_legend] = series; #if (DEBUG > 0) && (DEBUG < 2) qDebug() << "plot(x,y): -----"; @@ -791,7 +808,7 @@ class Madplotlib qDebug() << "show(): xrange [" << _xMin << "," << _xMax << "] " << " yrange [" << _yMin << "," << _yMax << "]"; #endif - + QPen axisPen(Qt::black); // default axis line color and width axisPen.setWidth(1); @@ -799,15 +816,22 @@ class Madplotlib QtCharts::QCategoryAxis* categoryX = NULL; if (_showXticks == SHOW_TICK || _showXticks == HIDE_TICK) { - axisX = new QtCharts::QValueAxis; + bool add = true; + if (_xAxisBottom){ + axisX = dynamic_cast(_xAxisBottom); + add = false; + }else{ + axisX = new QtCharts::QValueAxis; + } axisX->setGridLineVisible(_enableGrid); axisX->setTitleText(_xLabel); axisX->setLinePen(axisPen); axisX->setRange(_xMin, _xMax); axisX->setTickCount(_xTickCount); if (!_customLimits) axisX->applyNiceNumbers(); - _chart->addAxis(axisX, Qt::AlignBottom); - + if(add) + _chart->addAxis(axisX, Qt::AlignBottom); + _xAxisBottom = axisX; if (_showXticks == HIDE_TICK) axisX->setLabelsVisible(false); } @@ -829,23 +853,34 @@ class Madplotlib categoryX->setRange(_xMin, _xMax); categoryX->setTickCount(_xTicks.size()); + if(_xAxisBottom) + _chart->removeAxis(_xAxisBottom); _chart->addAxis(categoryX, Qt::AlignBottom); + _xAxisBottom = categoryX; } QtCharts::QValueAxis* axisY = NULL; QtCharts::QCategoryAxis* categoryY = NULL; if (_showYticks == SHOW_TICK || _showYticks == HIDE_TICK) // this is the default ticks setup { - axisY = new QtCharts::QValueAxis; + bool add = true; + if(_yAxisLeft){ + axisY = dynamic_cast(_yAxisLeft); + add = false; + }else{ + axisY = new QtCharts::QValueAxis; + } + axisY->setGridLineVisible(_enableGrid); axisY->setTitleText(_yLabel); axisY->setLinePen(axisPen); axisY->setRange(_yMin, _yMax); axisY->setTickCount(_yTickCount); if (!_customLimits) axisY->applyNiceNumbers(); - //axisY->setBase(8.0); // 1, 8, 64, 512, 4096 - _chart->addAxis(axisY, Qt::AlignLeft); - + if(add) + _chart->addAxis(axisY, Qt::AlignLeft); + _yAxisLeft = axisY; + if (_showYticks == HIDE_TICK) axisY->setLabelsVisible(false); } @@ -867,41 +902,39 @@ class Madplotlib categoryY->setRange(_yMin, _yMax); categoryY->setTickCount(_yTicks.size()); + if(_yAxisLeft) + _chart->removeAxis(_yAxisLeft); _chart->addAxis(categoryY, Qt::AlignLeft); + _yAxisLeft = categoryY; } /* Other possible customizations such as margins and background color */ - - //_chart->setMargins(QMargins(0,0,0,0)); - //_chart->setPlotAreaBackgroundBrush(QBrush(Qt::black)); - //_chart->setPlotAreaBackgroundVisible(true); - // Remove (fat) exterior margins from QChart _chart->layout()->setContentsMargins(0, 0, 0, 0); _chart->setBackgroundRoundness(0); /* Add series of data */ - - for (int i = 0; i < _seriesVec.size(); i++) + _chart->removeAllSeries(); + for(auto itr : _seriesVec) { - _chart->addSeries(_seriesVec[i]); + _chart->addSeries(itr.get()); if (_showXticks == SHOW_TICK || _showXticks == HIDE_TICK) { - _seriesVec[i]->attachAxis(axisX); + itr->attachAxis(axisX); } else if (_showXticks == SHOW_CUSTOM_TICK) { - _seriesVec[i]->attachAxis(categoryX); + itr->attachAxis(categoryX); } if (_showYticks == SHOW_TICK || _showYticks == HIDE_TICK) { - _seriesVec[i]->attachAxis(axisY); + itr->attachAxis(axisY); } else if (_showYticks == SHOW_CUSTOM_TICK) { - _seriesVec[i]->attachAxis(categoryY); + itr->attachAxis(categoryY); } } @@ -910,7 +943,7 @@ class Madplotlib // Take a screenshot of the widget before it's destroyed // so it can be saved later, when savefig() is invoked after show(). - _pixmap = _chartView->grab(); + _chartView->show(); @@ -918,14 +951,14 @@ class Madplotlib // However, is this chart is supposed to be a real widget, then do none of this. if (!_isWidget) { + _pixmap = _chartView->grab(); _chartView->setAttribute(Qt::WA_DeleteOnClose); // This deletes _chartView! QEventLoop loop; QObject::connect(_chartView, SIGNAL(destroyed()), &loop, SLOT(quit())); loop.exec(); // _chartView was automatically deleted. Release all the other resources! - for (int i = 0; i < _seriesVec.size(); i++) - delete _seriesVec[i]; + //_seriesVec.clear(); } #if (DEBUG > 0) && (DEBUG < 2) @@ -933,6 +966,9 @@ class Madplotlib #endif } + void clear(){ + _seriesVec.clear(); + } private: @@ -1024,7 +1060,8 @@ class Madplotlib QPixmap _pixmap; // show() screenshots the widget, savefig() writes it on the disk QtCharts::QChart* _chart; // manages the graphical representation of the chart's series, legends & axes QtCharts::QChartView* _chartView; // standalone widget that can display charts - QVector _seriesVec; // every plot() creates a new series of data that is stored here + QMap> _seriesVec; // every plot() creates a new series of data that is stored here + bool _isWidget; // true: show() doesn't block so this can be used as widget QString _legend; @@ -1051,4 +1088,8 @@ class Madplotlib qreal _yMax; // Y axis max limit bool _enableGrid; // flag that show/hides the background grid + QtCharts::QAbstractAxis* _yAxisLeft; + QtCharts::QAbstractAxis* _yAxisRight; + QtCharts::QAbstractAxis* _xAxisBottom; + QtCharts::QAbstractAxis* _xAxisTop; }; From 183ed8e950ada65697b7dcd5d6018e895f2b14df Mon Sep 17 00:00:00 2001 From: Emiliano Borghi Date: Thu, 15 Apr 2021 21:26:35 -0300 Subject: [PATCH 7/9] Add missing for std::shared_ptr --- Madplotlib.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Madplotlib.h b/Madplotlib.h index 708f486..30f31b0 100644 --- a/Madplotlib.h +++ b/Madplotlib.h @@ -8,6 +8,9 @@ * 2D plots inspired on matplotlib. */ #pragma once + +#include + #ifndef NO_EIGEN #include #endif From 187102435647bda825d1472d9cf76f508e202816 Mon Sep 17 00:00:00 2001 From: Olzhas Adiyatov Date: Fri, 27 Jan 2023 22:33:38 -0500 Subject: [PATCH 8/9] Updated CMakeLists.txt and fixed the example file. Reformated the header file. --- .gitignore | 1 + CMakeLists.txt | 8 +- Madplotlib.h | 1635 +++++++++++++++++++++++------------------------ eigen_tests.cpp | 2 +- 4 files changed, 796 insertions(+), 850 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d163863 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 64a6b1f..0799324 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,17 @@ cmake_minimum_required(VERSION 3.0) + +set(CMAKE_CXX_STANDARD 17) + project(madplotlib) + + include_directories(${CMAKE_CURRENT_LIST_DIR}) find_package(Qt5 REQUIRED COMPONENTS Charts) include_directories(${Qt5_Charts_INCLUDE_DIRS}) find_package(Eigen3 REQUIRED) -include_directories(${Eigen3_INCLUDE_DIRS}) add_executable(eigen_test eigen_tests.cpp) -target_link_libraries(eigen_test Qt5::Charts) \ No newline at end of file +target_link_libraries(eigen_test Qt5::Charts Eigen3::Eigen) \ No newline at end of file diff --git a/Madplotlib.h b/Madplotlib.h index 30f31b0..5604019 100644 --- a/Madplotlib.h +++ b/Madplotlib.h @@ -43,175 +43,170 @@ #define PLT_CONSTEXPR constexpr #endif -#define MO_KEYWORD_INPUT(name, type) \ -namespace tag{ \ - struct name { \ - typedef type Type; \ - typedef const Type& ConstRef; \ - typedef Type& Ref; \ - typedef ConstRef StorageType; \ - typedef const void* VoidType; \ - template \ - static PLT_CONSTEXPR bool AllowedType() { return std::is_same::value; } \ - static VoidType GetPtr(const Type& arg) { \ - return &arg; \ - } \ - template \ - static VoidType GetPtr(const T& arg) { \ - (void)arg; \ - return nullptr; \ - } \ - }; \ -} \ -namespace PLT_ARG_NAMESPACE { \ - static kwargs::TKeyword& name = kwargs::TKeyword::instance; \ -} - - -#define MO_KEYWORD_OUTPUT(name, type) \ -namespace tag{ \ - struct name { \ - typedef type Type; \ - typedef const Type& ConstRef; \ - typedef Type& Ref; \ - typedef Ref StorageType; \ - typedef void* VoidType; \ - template \ - static PLT_CONSTEXPR bool AllowedType() { return std::is_same::value; } \ - static VoidType GetPtr(Type& arg) { \ - return &arg; \ - } \ - template \ - static VoidType GetPtr(const T& arg) { \ - (void)arg; \ - return nullptr; \ - } \ - }; \ -} \ -namespace PLT_ARG_NAMESPACE { \ -static kwargs::TKeyword& name = kwargs::TKeyword::instance; \ -} +#define MO_KEYWORD_INPUT(name, type) \ + namespace tag { \ + struct name { \ + typedef type Type; \ + typedef const Type &ConstRef; \ + typedef Type &Ref; \ + typedef ConstRef StorageType; \ + typedef const void *VoidType; \ + template static PLT_CONSTEXPR bool AllowedType() { \ + return std::is_same::value; \ + } \ + static VoidType GetPtr(const Type &arg) { return &arg; } \ + template static VoidType GetPtr(const T &arg) { \ + (void)arg; \ + return nullptr; \ + } \ + }; \ + } \ + namespace PLT_ARG_NAMESPACE { \ + static kwargs::TKeyword &name = \ + kwargs::TKeyword::instance; \ + } + +#define MO_KEYWORD_OUTPUT(name, type) \ + namespace tag { \ + struct name { \ + typedef type Type; \ + typedef const Type &ConstRef; \ + typedef Type &Ref; \ + typedef Ref StorageType; \ + typedef void *VoidType; \ + template static PLT_CONSTEXPR bool AllowedType() { \ + return std::is_same::value; \ + } \ + static VoidType GetPtr(Type &arg) { return &arg; } \ + template static VoidType GetPtr(const T &arg) { \ + (void)arg; \ + return nullptr; \ + } \ + }; \ + } \ + namespace PLT_ARG_NAMESPACE { \ + static kwargs::TKeyword &name = kwargs::TKeyword::instance; \ + } namespace kwargs { - struct TaggedBase {}; - template - struct TaggedArgument : public TaggedBase { - typedef Tag TagType; - explicit TaggedArgument(typename Tag::StorageType val) - : arg(&val) { - } +struct TaggedBase {}; +template struct TaggedArgument : public TaggedBase { + typedef Tag TagType; + explicit TaggedArgument(typename Tag::StorageType val) : arg(&val) {} - typename Tag::VoidType get() const { - return arg; - } + typename Tag::VoidType get() const { return arg; } - protected: - typename Tag::VoidType arg; - }; +protected: + typename Tag::VoidType arg; +}; - template - struct TKeyword { - static TKeyword instance; - TaggedArgument operator=(typename Tag::StorageType data) { - return TaggedArgument(data); - } - }; - template - TKeyword TKeyword::instance; -} +template struct TKeyword { + static TKeyword instance; + TaggedArgument operator=(typename Tag::StorageType data) { + return TaggedArgument(data); + } +}; +template TKeyword TKeyword::instance; +} // namespace kwargs -template -struct ArgType; +template struct ArgType; -template -struct ArgType<0, T0, T...> { - typedef T0 type; +template struct ArgType<0, T0, T...> { + typedef T0 type; }; -template -struct ArgType { - typedef typename ArgType::type type; +template struct ArgType { + typedef typename ArgType::type type; }; -template -typename Tag::VoidType GetKeyImpl() { - return 0; +template typename Tag::VoidType GetKeyImpl() { + return 0; } -template -PLT_CONSTEXPR int CountTypeImpl(const U& value) { - return std::is_same::value ? 1 : 0; +template PLT_CONSTEXPR int CountTypeImpl(const U &value) { + return std::is_same::value ? 1 : 0; } template -PLT_CONSTEXPR int CountTypeImpl(const U& value, const Args&... args) { - return CountTypeImpl(args...) + (std::is_same::value ? 1 : 0); +PLT_CONSTEXPR int CountTypeImpl(const U &value, const Args &...args) { + return CountTypeImpl(args...) + + (std::is_same::value ? 1 : 0); } template -PLT_CONSTEXPR int CountType(const Args&... args) { - return CountTypeImpl(args...); +PLT_CONSTEXPR int CountType(const Args &...args) { + return CountTypeImpl(args...); } template -auto GetPositionalInput(Args&&... as) -> decltype(std::get(std::forward_as_tuple(std::forward(as)...))) { - return std::get(std::forward_as_tuple(std::forward(as)...)); +auto GetPositionalInput(Args &&...as) + -> decltype(std::get(std::forward_as_tuple(std::forward(as)...))) { + return std::get(std::forward_as_tuple(std::forward(as)...)); } template -typename std::enable_if::value, typename Tag::VoidType>::type - GetKeyImpl(const T& arg, const Args&... args) { - return std::is_same::value ? const_cast(arg.get()) : const_cast(GetKeyImpl(args...)); +typename std::enable_if::value, + typename Tag::VoidType>::type +GetKeyImpl(const T &arg, const Args &...args) { + return std::is_same::value + ? const_cast(arg.get()) + : const_cast(GetKeyImpl(args...)); } template -typename std::enable_if::value, typename Tag::VoidType>::type - GetKeyImpl(const T& arg, const Args&... args) { +typename std::enable_if::value, + typename Tag::VoidType>::type +GetKeyImpl(const T &arg, const Args &...args) { #ifdef __GNUC__ - //static_assert(CountType(arg, args...) <= 1, "Cannot infer type when there are multiple variadic Params with desired type"); + // static_assert(CountType(arg, args...) <= 1, "Cannot + // infer type when there are multiple variadic Params with desired type"); #endif - return Tag::template AllowedType() && Infer ? // This infers the type - Tag::GetPtr(arg) - : const_cast(GetKeyImpl(args...)); + return Tag::template AllowedType() && Infer + ? // This infers the type + Tag::GetPtr(arg) + : const_cast(GetKeyImpl(args...)); } template -typename Tag::ConstRef GetKeywordInput(const Args&... args) { - const void* ptr = GetKeyImpl(args...); - assert(ptr); - return *(static_cast(ptr)); +typename Tag::ConstRef GetKeywordInput(const Args &...args) { + const void *ptr = GetKeyImpl(args...); + assert(ptr); + return *(static_cast(ptr)); } template -typename Tag::ConstRef GetKeywordInputDefault(typename Tag::ConstRef def, const Args&... args) { - const void* ptr = GetKeyImpl(args...); - if (ptr) - return *static_cast(ptr); - return def; +typename Tag::ConstRef GetKeywordInputDefault(typename Tag::ConstRef def, + const Args &...args) { + const void *ptr = GetKeyImpl(args...); + if (ptr) + return *static_cast(ptr); + return def; } template -const typename Tag::Type* GetKeywordInputOptional(const Args&... args) { - const void* ptr = GetKeyImpl(args...); - if (ptr) - return static_cast(ptr); - return nullptr; +const typename Tag::Type *GetKeywordInputOptional(const Args &...args) { + const void *ptr = GetKeyImpl(args...); + if (ptr) + return static_cast(ptr); + return nullptr; } template -typename Tag::Ref GetKeywordOutput(const Args&... args) { - static_assert(!std::is_const::value, "Tag type is not an output tag"); - void* ptr = GetKeyImpl(args...); - assert(ptr); - return *(static_cast(ptr)); +typename Tag::Ref GetKeywordOutput(const Args &...args) { + static_assert(!std::is_const::value, + "Tag type is not an output tag"); + void *ptr = GetKeyImpl(args...); + assert(ptr); + return *(static_cast(ptr)); } template -typename Tag::Type* GetKeywordOutputOptional(const Args&... args) { - static_assert(!std::is_const::value, "Tag type is not an output tag"); - void* ptr = GetKeyImpl(args...); - if (ptr) - return (static_cast(ptr)); - return nullptr; +typename Tag::Type *GetKeywordOutputOptional(const Args &...args) { + static_assert(!std::is_const::value, + "Tag type is not an output tag"); + void *ptr = GetKeyImpl(args...); + if (ptr) + return (static_cast(ptr)); + return nullptr; } MO_KEYWORD_INPUT(x, Eigen::ArrayXf) @@ -228,871 +223,817 @@ MO_KEYWORD_INPUT(markersize, qreal) /*template struct is_matrix_expression : std::false_type {}; template -struct is_matrix_expression() = std::declval(), void())> : std::true_type {};*/ +struct is_matrix_expression() = +std::declval(), void())> : std::true_type {};*/ // Not sure if there are limitations to this but it seems to work on 2013 -template +template struct is_matrix_expression - : std::is_base_of >, std::decay_t > -{}; - - + : std::is_base_of>, + std::decay> {}; /* Debug control */ -#define DEBUG 0 // level 0: debug msgs are disabled - // level 1: print method calls - // level 2: print method calls + data +#define DEBUG \ + 0 // level 0: debug msgs are disabled + // level 1: print method calls + // level 2: print method calls + data /* Global definitions */ -#define SHOW_TICK 1 -#define HIDE_TICK 2 -#define SHOW_CUSTOM_TICK 4 +#define SHOW_TICK 1 +#define HIDE_TICK 2 +#define SHOW_CUSTOM_TICK 4 -#define DEFAULT_LEGEND "" -#define DEFAULT_MARKER "-" -#define DEFAULT_ALPHA 1.0f -#define DEFAULT_COLOR "none" -#define DEFAULT_EDGECOLOR "none" -#define DEFAULT_LINEW 2 -#define DEFAULT_MARKERSZ 6.0f +#define DEFAULT_LEGEND "" +#define DEFAULT_MARKER "-" +#define DEFAULT_ALPHA 1.0f +#define DEFAULT_COLOR "none" +#define DEFAULT_EDGECOLOR "none" +#define DEFAULT_LINEW 2 +#define DEFAULT_MARKERSZ 6.0f #ifdef NO_EIGEN #error COMPILATION MUST GO THOUGH WITHOUT EIGEN CODE. #endif - -class Madplotlib -{ +class Madplotlib { public: - Madplotlib(bool isWidget = false) - : _chart(NULL), _chartView(NULL), _isWidget(isWidget) - { + Madplotlib(bool isWidget = false) + : _chart(NULL), _chartView(NULL), _isWidget(isWidget) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "Madplotlib(): isWidget=" << isWidget; + qDebug() << "Madplotlib(): isWidget=" << isWidget; #endif - _xAxisTop = _xAxisBottom = _yAxisLeft = _yAxisRight = nullptr; - _chart = new QtCharts::QChart(); - - _chartView = new QtCharts::QChartView(_chart); - - _enableGrid = false; - _customLimits = false; - _xMin = _xMax = _yMin = _yMax = 0; - - _showXticks = _showYticks = SHOW_TICK; - _xTickCount = 7; - _yTickCount = 5; - - _colorIdx = 0; - _colors.push_back(QColor(0x1f77b4)); - _colors.push_back(QColor(0xff7f0e)); - _colors.push_back(QColor(0x2ca02c)); - _colors.push_back(QColor(0xd62728)); - _colors.push_back(QColor(0x9467bd)); - _colors.push_back(QColor(0x8c564b)); - _colors.push_back(QColor(0xe377c2)); - _colors.push_back(QColor(0x7f7f7f)); - _colors.push_back(QColor(0xbcbd22)); - _colors.push_back(QColor(0x17becf)); - } - - void axis(QString cmd) - { + _xAxisTop = _xAxisBottom = _yAxisLeft = _yAxisRight = nullptr; + _chart = new QtCharts::QChart(); + + _chartView = new QtCharts::QChartView(_chart); + + _enableGrid = false; + _customLimits = false; + _xMin = _xMax = _yMin = _yMax = 0; + + _showXticks = _showYticks = SHOW_TICK; + _xTickCount = 7; + _yTickCount = 5; + + _colorIdx = 0; + _colors.push_back(QColor(0x1f77b4)); + _colors.push_back(QColor(0xff7f0e)); + _colors.push_back(QColor(0x2ca02c)); + _colors.push_back(QColor(0xd62728)); + _colors.push_back(QColor(0x9467bd)); + _colors.push_back(QColor(0x8c564b)); + _colors.push_back(QColor(0xe377c2)); + _colors.push_back(QColor(0x7f7f7f)); + _colors.push_back(QColor(0xbcbd22)); + _colors.push_back(QColor(0x17becf)); + } + + void axis(QString cmd) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "axis(): cmd=" << cmd; + qDebug() << "axis(): cmd=" << cmd; #endif - if (cmd == "off") - { - _showYticks = _showXticks = HIDE_TICK; - } - else if (cmd == "xoff") - { - _showXticks = HIDE_TICK; - } - else if (cmd == "yoff") - { - _showYticks = HIDE_TICK; - } - else - { - qCritical() << "axis()!!! options are 'off', 'xoff' and 'yoff'."; - return; - } + if (cmd == "off") { + _showYticks = _showXticks = HIDE_TICK; + } else if (cmd == "xoff") { + _showXticks = HIDE_TICK; + } else if (cmd == "yoff") { + _showYticks = HIDE_TICK; + } else { + qCritical() << "axis()!!! options are 'off', 'xoff' and 'yoff'."; + return; } + } - /* axis(): gets the current axes limits [xMin, xMax, yMin, yMax]. - */ - void axis(qreal* xMin, qreal* xMax, qreal* yMin, qreal* yMax) - { + /* axis(): gets the current axes limits [xMin, xMax, yMin, yMax]. + */ + void axis(qreal *xMin, qreal *xMax, qreal *yMin, qreal *yMax) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "axis(): _xMin=" << _xMin << " _xMax=" << _xMax << " _yMin=" << _yMin << " _yMax=" << _yMax; + qDebug() << "axis(): _xMin=" << _xMin << " _xMax=" << _xMax + << " _yMin=" << _yMin << " _yMax=" << _yMax; #endif - *xMin = _xMin; - *xMax = _xMax; - *yMin = _yMin; - *yMax = _yMax; - } - - /* axis(): sets the viewport of the axis by a list of [xMin, xMax, yMin, yMax]. - */ - void axis(const qreal& xMin, qreal xMax, const qreal& yMin, const qreal& yMax) - { + *xMin = _xMin; + *xMax = _xMax; + *yMin = _yMin; + *yMax = _yMax; + } + + /* axis(): sets the viewport of the axis by a list of [xMin, xMax, yMin, + * yMax]. + */ + void axis(const qreal &xMin, qreal xMax, const qreal &yMin, + const qreal &yMax) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "axis(): xMin=" << xMin << " xMax=" << xMax << " yMin=" << yMin << " yMax=" << yMax; + qDebug() << "axis(): xMin=" << xMin << " xMax=" << xMax << " yMin=" << yMin + << " yMax=" << yMax; #endif - _xMin = xMin; - _xMax = xMax; - _yMin = yMin; - _yMax = yMax; - _customLimits = true; - } - - /* xlim(): sets the x limits of the current axes. - */ - void xlim(const qreal& xMin, const qreal& xMax) - { + _xMin = xMin; + _xMax = xMax; + _yMin = yMin; + _yMax = yMax; + _customLimits = true; + } + + /* xlim(): sets the x limits of the current axes. + */ + void xlim(const qreal &xMin, const qreal &xMax) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "xlim(): xMin=" << xMin << " xMax=" << xMax; + qDebug() << "xlim(): xMin=" << xMin << " xMax=" << xMax; #endif - _xMin = xMin; - _xMax = xMax; - _customLimits = true; - } - - /* ylim(): sets the x limits of the current axes. - */ - void ylim(const qreal& yMin, const qreal& yMax) - { + _xMin = xMin; + _xMax = xMax; + _customLimits = true; + } + + /* ylim(): sets the x limits of the current axes. + */ + void ylim(const qreal &yMin, const qreal &yMax) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "ylim(): yMin=" << yMin << " yMax=" << yMax; + qDebug() << "ylim(): yMin=" << yMin << " yMax=" << yMax; #endif - _yMin = yMin; - _yMax = yMax; - _customLimits = true; - } - - /* title(): defines the title of the chart. - */ - void title(QString string) - { + _yMin = yMin; + _yMax = yMax; + _customLimits = true; + } + + /* title(): defines the title of the chart. + */ + void title(QString string) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "title(): string=" << string; + qDebug() << "title(): string=" << string; #endif - _title = string; - } + _title = string; + } - /* xlabel(): defines the label displayed below the x axis. - */ - void xlabel(QString label) - { + /* xlabel(): defines the label displayed below the x axis. + */ + void xlabel(QString label) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "xlabel(): label=" << label; + qDebug() << "xlabel(): label=" << label; #endif - _xLabel = label; - } + _xLabel = label; + } - /* ylabel(): defines the label displayed to the left of the y axis. - */ - void ylabel(QString label) - { + /* ylabel(): defines the label displayed to the left of the y axis. + */ + void ylabel(QString label) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "ylabel(): label=" << label; + qDebug() << "ylabel(): label=" << label; #endif - _yLabel = label; - } + _yLabel = label; + } - /* legend(): defines the position of the legend label inside the chart. - */ - void legend() - { - _legendPos = "lower center"; - } + /* legend(): defines the position of the legend label inside the chart. + */ + void legend() { _legendPos = "lower center"; } - /* legend(): defines the position of the legend label inside the chart. - */ - void legend(QString cmd) - { - _legendPos = _parseLegendPos(cmd); - } + /* legend(): defines the position of the legend label inside the chart. + */ + void legend(QString cmd) { _legendPos = _parseLegendPos(cmd); } - /* grid(): enables or disables the background grid of the chart. - */ - void grid(bool status) - { + /* grid(): enables or disables the background grid of the chart. + */ + void grid(bool status) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "grid(): status=" << status; + qDebug() << "grid(): status=" << status; #endif - _enableGrid = status; - } + _enableGrid = status; + } - /* savefig(): saves the chart displayed by show() as an image on the disk. - */ - void savefig(QString filename) - { + /* savefig(): saves the chart displayed by show() as an image on the disk. + */ + void savefig(QString filename) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "savefig(): filename=" << filename; + qDebug() << "savefig(): filename=" << filename; #endif - if (!_pixmap.isNull()) - _pixmap.save(filename); - else if(_isWidget && _chartView){ - _pixmap = _chartView->grab(); - } + if (!_pixmap.isNull()) + _pixmap.save(filename); + else if (_isWidget && _chartView) { + _pixmap = _chartView->grab(); } + } - /* xticks(): sets the x-limits of the current tick locations and labels. - */ - void xticks(const Eigen::ArrayXf& values, const QVector& labels) - { + /* xticks(): sets the x-limits of the current tick locations and labels. + */ + void xticks(const Eigen::ArrayXf &values, const QVector &labels) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "xticks(): values.sz=" << values.rows() << " labels.sz=" << labels.size(); + qDebug() << "xticks(): values.sz=" << values.rows() + << " labels.sz=" << labels.size(); #endif - if (values.rows() == 0 && labels.size() == 0) - { - _showXticks = HIDE_TICK; - return; - } + if (values.rows() == 0 && labels.size() == 0) { + _showXticks = HIDE_TICK; + return; + } - if (values.rows() != labels.size()) - { - qCritical() << "xticks(): the amount of values and labels must match!"; - return; - } + if (values.rows() != labels.size()) { + qCritical() << "xticks(): the amount of values and labels must match!"; + return; + } - for (int i = 0; i < values.rows(); i++) - _xTicks.push_back(QPair(labels[i], values[i])); + for (int i = 0; i < values.rows(); i++) + _xTicks.push_back(QPair(labels[i], values[i])); - _showXticks = SHOW_CUSTOM_TICK; + _showXticks = SHOW_CUSTOM_TICK; #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "xticks(): xticks.sz=" << _xTicks.size(); - for (int i = 0; i < _xTicks.size(); i++) - qDebug() << "\t" << _xTicks[i].second << " = " << _xTicks[i].first; + qDebug() << "xticks(): xticks.sz=" << _xTicks.size(); + for (int i = 0; i < _xTicks.size(); i++) + qDebug() << "\t" << _xTicks[i].second << " = " << _xTicks[i].first; #endif - } + } - /* yticks(): sets the y-limits of the current tick locations and labels. - */ - void yticks(const Eigen::ArrayXf& values, const QVector& labels) - { + /* yticks(): sets the y-limits of the current tick locations and labels. + */ + void yticks(const Eigen::ArrayXf &values, const QVector &labels) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "yticks(): values.sz=" << values.rows() << " labels.sz=" << labels.size(); + qDebug() << "yticks(): values.sz=" << values.rows() + << " labels.sz=" << labels.size(); #endif - if (values.rows() == 0 && labels.size() == 0) - { - _showYticks = HIDE_TICK; - return; - } + if (values.rows() == 0 && labels.size() == 0) { + _showYticks = HIDE_TICK; + return; + } - if (values.rows() != labels.size()) - { - qCritical() << "PlotLib::xticks(): the amount of values and labels must match!" ; - return; - } + if (values.rows() != labels.size()) { + qCritical() + << "PlotLib::xticks(): the amount of values and labels must match!"; + return; + } - for (int i = 0; i < values.rows(); i++) - _yTicks.push_back(QPair(labels[i], values[i])); + for (int i = 0; i < values.rows(); i++) + _yTicks.push_back(QPair(labels[i], values[i])); - _showYticks = SHOW_CUSTOM_TICK; + _showYticks = SHOW_CUSTOM_TICK; #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "yticks(): yticks.sz=" << _yTicks.size(); - for (int i = 0; i < _yTicks.size(); i++) - qDebug() << "\t" << _yTicks[i].second << " = " << _yTicks[i].first; + qDebug() << "yticks(): yticks.sz=" << _yTicks.size(); + for (int i = 0; i < _yTicks.size(); i++) + qDebug() << "\t" << _yTicks[i].second << " = " << _yTicks[i].first; #endif - } + } - /* locator_params(): reduce or increase the amount of ticks for each axis. - */ - void locator_params(QString axis, int nbins) - { + /* locator_params(): reduce or increase the amount of ticks for each axis. + */ + void locator_params(QString axis, int nbins) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "locator_params(): axis=" << axis << " nbins=" << nbins; + qDebug() << "locator_params(): axis=" << axis << " nbins=" << nbins; #endif - if (axis == "x") - { - _xTickCount = nbins; - } - else if (axis == "y") - { - _yTickCount = nbins; - } - else if (axis == "both") - { - _yTickCount = _xTickCount = nbins; - } - else - { - qCritical() << "locator_params(): '" << axis << "' is not a valid option."; - return; - } + if (axis == "x") { + _xTickCount = nbins; + } else if (axis == "y") { + _yTickCount = nbins; + } else if (axis == "both") { + _yTickCount = _xTickCount = nbins; + } else { + qCritical() << "locator_params(): '" << axis + << "' is not a valid option."; + return; } - - template - typename std::enable_if::value>::type plot(const Eigen::ArrayXf& y, const T& arg1, const Args&... args) - { + } + + template + typename std::enable_if::value>::type + plot(const Eigen::ArrayXf &y, const T &arg1, const Args &...args) { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "plot(y): marker=" << marker << " alpha=" << alpha << - " color=" << color << " edgecolor=" << edgecolor << - " linewidth=" << linewidth << " markersize=" << markersize; + qDebug() << "plot(y): marker=" << marker << " alpha=" << alpha + << " color=" << color << " edgecolor=" << edgecolor + << " linewidth=" << linewidth << " markersize=" << markersize; #endif - if (y.rows() == 0) - { - qCritical() << "plot(y): axis size must be > 0 but its " << y.rows(); - exit(-1); - } + if (y.rows() == 0) { + qCritical() << "plot(y): axis size must be > 0 but its " << y.rows(); + exit(-1); + } - // number of x values needed to accompany the y values - int num_items = y.rows(); - - // make up X data and plot into series, but take into account that xlim() - // could have been called with the start and end of x series. - Eigen::ArrayXf x = Eigen::ArrayXf(y.rows()); - qreal x_inc = 1; - if (_customLimits && (_xMin != _xMax)) - { - qreal xrange = _xMax - _xMin; - x_inc = xrange / y.rows(); - } + // number of x values needed to accompany the y values + int num_items = y.rows(); + + // make up X data and plot into series, but take into account that xlim() + // could have been called with the start and end of x series. + Eigen::ArrayXf x = Eigen::ArrayXf(y.rows()); + qreal x_inc = 1; + if (_customLimits && (_xMin != _xMax)) { + qreal xrange = _xMax - _xMin; + x_inc = xrange / y.rows(); + } - qreal x_value = _xMin; - for (int i = 0; i < num_items; i++) - { - x[i] = x_value; - x_value += x_inc; + qreal x_value = _xMin; + for (int i = 0; i < num_items; i++) { + x[i] = x_value; + x_value += x_inc; #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(y): generated x[" << i << "]=" << x[i]; + qDebug() << "plot(y): generated x[" << i << "]=" << x[i]; #endif - } - plotXY(x, y, arg1, args...); } + plotXY(x, y, arg1, args...); + } + + /* plot(): called when user needs to put data on a chart. + * x: an array that stores x axis values. + * y: an array that stores y axis values. + * marker: chart types. "-" for line plot and "o" for scatter plot. + * alpha: defines the transparency level of the color. + * color: defines the color used to draw the data. + * edgecolor: defines the edge color of "o" marker. + * linewidth: defines the width of the pen used to draw "-" marker. + * markersize: defines the size of "o" marker. + */ + template + typename std::enable_if::value>::type + plot(const Eigen::ArrayXf &x, const T &y, const Args &...args) { + plotXY(x, y, args...); + } + + template + void plotXY(const Eigen::ArrayXf &x, const Eigen::ArrayXf &y, + const Args &...args) { + const QString marker = + GetKeywordInputDefault(DEFAULT_MARKER, args...); + const QString label = + GetKeywordInputDefault(DEFAULT_LEGEND, args...); + const qreal &alpha = + GetKeywordInputDefault(DEFAULT_ALPHA, args...); + const QColor color = + GetKeywordInputDefault(DEFAULT_COLOR, args...); + const quint32 &linewidth = + GetKeywordInputDefault(DEFAULT_LINEW, args...); + const QColor edgecolor = + GetKeywordInputDefault(DEFAULT_EDGECOLOR, args...); + const qreal &markersize = + GetKeywordInputDefault(DEFAULT_MARKERSZ, args...); - - /* plot(): called when user needs to put data on a chart. - * x: an array that stores x axis values. - * y: an array that stores y axis values. - * marker: chart types. "-" for line plot and "o" for scatter plot. - * alpha: defines the transparency level of the color. - * color: defines the color used to draw the data. - * edgecolor: defines the edge color of "o" marker. - * linewidth: defines the width of the pen used to draw "-" marker. - * markersize: defines the size of "o" marker. - */ - template - typename std::enable_if::value>::type plot(const Eigen::ArrayXf& x, const T& y, const Args&... args) - { - plotXY(x, y, args...); - } - - template - void plotXY(const Eigen::ArrayXf& x, const Eigen::ArrayXf& y, const Args&... args) - { - const QString marker = GetKeywordInputDefault(DEFAULT_MARKER, args...); - const QString label = GetKeywordInputDefault(DEFAULT_LEGEND, args...); - const qreal& alpha = GetKeywordInputDefault(DEFAULT_ALPHA, args...); - const QColor color = GetKeywordInputDefault(DEFAULT_COLOR, args...); - const quint32& linewidth = GetKeywordInputDefault(DEFAULT_LINEW, args...); - const QColor edgecolor = GetKeywordInputDefault(DEFAULT_EDGECOLOR, args...); - const qreal& markersize = GetKeywordInputDefault(DEFAULT_MARKERSZ, args...); - - #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "plot(x,y): marker:" << marker << " alpha:" << alpha << - " color:" << color << " edgecolor:" << edgecolor << - " linewidth:" << linewidth << " markersize:" << markersize; + qDebug() << "plot(x,y): marker:" << marker << " alpha:" << alpha + << " color:" << color << " edgecolor:" << edgecolor + << " linewidth:" << linewidth << " markersize:" << markersize; #endif - if (marker != "-" && marker != "--" && marker != "." && marker != "o" && marker != "s") - { - qCritical() << "plot(x,y): unknown marker '" << marker << "'."; - return; - } + if (marker != "-" && marker != "--" && marker != "." && marker != "o" && + marker != "s") { + qCritical() << "plot(x,y): unknown marker '" << marker << "'."; + return; + } - if (x.rows() != y.rows()) - { - qCritical() << "plot(x,y): x.sz=" << x.cols() << " != y.sz=" << y.rows(); - exit(-1); - } + if (x.rows() != y.rows()) { + qCritical() << "plot(x,y): x.sz=" << x.cols() << " != y.sz=" << y.rows(); + exit(-1); + } - if (x.rows() == 0 || y.rows() == 0) - { - qCritical() << "plot(x,y): axis size must be > 0 but it is x.sz=" << x.rows() << " y.sz=" << y.rows(); - exit(-1); - } + if (x.rows() == 0 || y.rows() == 0) { + qCritical() << "plot(x,y): axis size must be > 0 but it is x.sz=" + << x.rows() << " y.sz=" << y.rows(); + exit(-1); + } - // Make a copy because it's show() who setup these things - _legend = label; - - // find min and max values to define the range of the X axis - qreal xMin = x.minCoeff(); - qreal xMax = x.maxCoeff(); - if (xMin < _xMin) - _xMin = xMin; - if (xMax > _xMax) - _xMax = xMax; - - // find min and max values to stablish the range of the Y axis - // however, if a new series brings more xtreme values, we need to respect that! - qreal yMin = y.minCoeff(); - qreal yMax = y.maxCoeff(); - if (yMin < _yMin) - _yMin = yMin; - if (yMax > _yMax) - _yMax = yMax; + // Make a copy because it's show() who setup these things + _legend = label; + + // find min and max values to define the range of the X axis + qreal xMin = x.minCoeff(); + qreal xMax = x.maxCoeff(); + if (xMin < _xMin) + _xMin = xMin; + if (xMax > _xMax) + _xMax = xMax; + + // find min and max values to stablish the range of the Y axis + // however, if a new series brings more xtreme values, we need to respect + // that! + qreal yMin = y.minCoeff(); + qreal yMax = y.maxCoeff(); + if (yMin < _yMin) + _yMin = yMin; + if (yMax > _yMax) + _yMax = yMax; #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(x,y): xrange [" << _xMin << "," << _xMax << - "] yrange [" << _yMin << "," << _yMax << "]"; + qDebug() << "plot(x,y): xrange [" << _xMin << "," << _xMax << "] yrange [" + << _yMin << "," << _yMax << "]"; #endif - std::shared_ptr series; - auto itr = _seriesVec.find(_legend); - if(itr != _seriesVec.end()){ - series = *itr; - }else{ - if (marker == "o" || marker == "s") // it's a scatter plot! - { - #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(x,y): scatter plot"; - #endif - QtCharts::QScatterSeries* s = new QtCharts::QScatterSeries(); - s->setMarkerSize(markersize); // symbol size - - if (marker == "o") - s->setMarkerShape(QtCharts::QScatterSeries::MarkerShapeCircle); - - if (marker == "s") - s->setMarkerShape(QtCharts::QScatterSeries::MarkerShapeRectangle); - - series.reset((QtCharts::QXYSeries*)s); - series->setUseOpenGL(true); - } - else // draw line - { - #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(x,y): line plot"; - #endif - series.reset(new QtCharts::QLineSeries()); - series->setUseOpenGL(true); - } - } - // Call a string parser! Ex: "label=Trump Tweets" becomes "Trump Tweets" - _parseLegend(); - if (_legend.size()) - { + std::shared_ptr series; + auto itr = _seriesVec.find(_legend); + if (itr != _seriesVec.end()) { + series = *itr; + } else { + if (marker == "o" || marker == "s") // it's a scatter plot! + { #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(x,y): label=" << _legend; + qDebug() << "plot(x,y): scatter plot"; #endif - series->setName(_legend); - } - - if(series->count() == x.rows()){ - for (int i = 0; i < x.rows(); i++) - series->replace(i, x[i], y[i]); - }else{ - series->clear(); - for (int i = 0; i < x.rows(); i++) - { + QtCharts::QScatterSeries *s = new QtCharts::QScatterSeries(); + s->setMarkerSize(markersize); // symbol size + + if (marker == "o") + s->setMarkerShape(QtCharts::QScatterSeries::MarkerShapeCircle); + + if (marker == "s") + s->setMarkerShape(QtCharts::QScatterSeries::MarkerShapeRectangle); + + series.reset((QtCharts::QXYSeries *)s); + series->setUseOpenGL(true); + } else // draw line + { #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(x,y): x[" << i << "]=" << x[i] << " y[" << i << "]=" << y[i]; + qDebug() << "plot(x,y): line plot"; #endif - series->append(x[i], y[i]); - } - } + series.reset(new QtCharts::QLineSeries()); + series->setUseOpenGL(true); + } + } + // Call a string parser! Ex: "label=Trump Tweets" becomes "Trump Tweets" + _parseLegend(); + if (_legend.size()) { +#if (DEBUG > 1) && (DEBUG < 3) + qDebug() << "plot(x,y): label=" << _legend; +#endif + series->setName(_legend); + } + + if (series->count() == x.rows()) { + for (int i = 0; i < x.rows(); i++) + series->replace(i, x[i], y[i]); + } else { + series->clear(); + for (int i = 0; i < x.rows(); i++) { +#if (DEBUG > 1) && (DEBUG < 3) + qDebug() << "plot(x,y): x[" << i << "]=" << x[i] << " y[" << i + << "]=" << y[i]; +#endif + series->append(x[i], y[i]); + } + } - // Customize series color and transparency - QColor fillColor = color; - if (fillColor == DEFAULT_COLOR) - fillColor = _colors[_colorIdx++]; - fillColor.setAlphaF(alpha); + // Customize series color and transparency + QColor fillColor = color; + if (fillColor == DEFAULT_COLOR) + fillColor = _colors[_colorIdx++]; + fillColor.setAlphaF(alpha); - QPen pen = series->pen(); - pen.setWidth(linewidth); + QPen pen = series->pen(); + pen.setWidth(linewidth); - if (marker == "o" || marker == "s") - { - if (edgecolor == DEFAULT_EDGECOLOR) - { - pen.setColor(fillColor); // outline should be invisible + if (marker == "o" || marker == "s") { + if (edgecolor == DEFAULT_EDGECOLOR) { + pen.setColor(fillColor); // outline should be invisible #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(x,y): fillColor=" << fillColor; + qDebug() << "plot(x,y): fillColor=" << fillColor; #endif - } - else - { + } else { #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "plot(x,y): edgecolor=" << edgecolor; + qDebug() << "plot(x,y): edgecolor=" << edgecolor; #endif - QColor edgeColor = edgecolor; - edgeColor.setAlphaF(alpha); - pen.setColor(edgeColor); // create circle outline - } - } - else if (marker == "--") - { - pen.setStyle(Qt::DashLine); - pen.setColor(fillColor); - } - else if (marker == ".") - { - pen.setStyle(Qt::DotLine); - pen.setColor(fillColor); - } - else // marker == "-" - { - pen.setColor(fillColor); - } + QColor edgeColor = edgecolor; + edgeColor.setAlphaF(alpha); + pen.setColor(edgeColor); // create circle outline + } + } else if (marker == "--") { + pen.setStyle(Qt::DashLine); + pen.setColor(fillColor); + } else if (marker == ".") { + pen.setStyle(Qt::DotLine); + pen.setColor(fillColor); + } else // marker == "-" + { + pen.setColor(fillColor); + } - series->setPen(pen); - series->setBrush(QBrush(fillColor)); + series->setPen(pen); + series->setBrush(QBrush(fillColor)); - if (_colorIdx >= _colors.size()) - _colorIdx = 0; + if (_colorIdx >= _colors.size()) + _colorIdx = 0; - //_seriesVec.push_back(series); - _seriesVec[_legend] = series; + //_seriesVec.push_back(series); + _seriesVec[_legend] = series; #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "plot(x,y): -----"; + qDebug() << "plot(x,y): -----"; #endif - } + } - /* show(): displays all the data added through plot() calls. - */ - void show() - { + /* show(): displays all the data added through plot() calls. + */ + void show() { #if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "show(): " << _title; + qDebug() << "show(): " << _title; #endif - if (!_seriesVec.size()) - { - qCritical() << "show()!!! Must set the data with plot() before show()."; - return; - } + if (!_seriesVec.size()) { + qCritical() << "show()!!! Must set the data with plot() before show()."; + return; + } - /* Customize chart title */ - - QFont font; - font.setPixelSize(12); - font.setWeight(QFont::Bold); - _chart->setTitleFont(font); - _chart->setTitle(_title); - - //TODO: investigate detaching the legend for custom positioning - //https://doc.qt.io/qt-5/qtcharts-legend-example.html - - if (_legendPos.size()) - { - if (_legendPos == "lower center") // 9 - _chart->legend()->setAlignment(Qt::AlignBottom); - else if (_legendPos == "upper center") // 8 - _chart->legend()->setAlignment(Qt::AlignTop); - else if (_legendPos == "center right") // 7 - _chart->legend()->setAlignment(Qt::AlignRight); - else if (_legendPos == "center left") // 6 - _chart->legend()->setAlignment(Qt::AlignLeft); - else - { - qCritical() << "show()!!!" << _legendPos << " is not a valid legend position."; - _chart->legend()->setAlignment(Qt::AlignBottom); - } - } + /* Customize chart title */ + + QFont font; + font.setPixelSize(12); + font.setWeight(QFont::Bold); + _chart->setTitleFont(font); + _chart->setTitle(_title); + + // TODO: investigate detaching the legend for custom positioning + // https://doc.qt.io/qt-5/qtcharts-legend-example.html + + if (_legendPos.size()) { + if (_legendPos == "lower center") // 9 + _chart->legend()->setAlignment(Qt::AlignBottom); + else if (_legendPos == "upper center") // 8 + _chart->legend()->setAlignment(Qt::AlignTop); + else if (_legendPos == "center right") // 7 + _chart->legend()->setAlignment(Qt::AlignRight); + else if (_legendPos == "center left") // 6 + _chart->legend()->setAlignment(Qt::AlignLeft); + else { + qCritical() << "show()!!!" << _legendPos + << " is not a valid legend position."; + _chart->legend()->setAlignment(Qt::AlignBottom); + } + } - if (_legend.size()) - _chart->legend()->setVisible(true); - else - _chart->legend()->setVisible(false); + if (_legend.size()) + _chart->legend()->setVisible(true); + else + _chart->legend()->setVisible(false); - /* Customize X, Y axis and categories */ + /* Customize X, Y axis and categories */ #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "show(): xrange [" << _xMin << "," << _xMax << "] " << - " yrange [" << _yMin << "," << _yMax << "]"; + qDebug() << "show(): xrange [" << _xMin << "," << _xMax << "] " + << " yrange [" << _yMin << "," << _yMax << "]"; #endif - - QPen axisPen(Qt::black); // default axis line color and width - axisPen.setWidth(1); - - QtCharts::QValueAxis* axisX = NULL; - QtCharts::QCategoryAxis* categoryX = NULL; - if (_showXticks == SHOW_TICK || _showXticks == HIDE_TICK) - { - bool add = true; - if (_xAxisBottom){ - axisX = dynamic_cast(_xAxisBottom); - add = false; - }else{ - axisX = new QtCharts::QValueAxis; - } - axisX->setGridLineVisible(_enableGrid); - axisX->setTitleText(_xLabel); - axisX->setLinePen(axisPen); - axisX->setRange(_xMin, _xMax); - axisX->setTickCount(_xTickCount); - if (!_customLimits) axisX->applyNiceNumbers(); - if(add) - _chart->addAxis(axisX, Qt::AlignBottom); - _xAxisBottom = axisX; - if (_showXticks == HIDE_TICK) - axisX->setLabelsVisible(false); - } - else if (_showXticks == SHOW_CUSTOM_TICK) - { - categoryX = new QtCharts::QCategoryAxis(); - categoryX->setGridLineVisible(_enableGrid); - categoryX->setLinePen(axisPen); - - if (_showXticks && _xTicks.size()) - for (int i = 0; i < _xTicks.size(); i++) - { + + QPen axisPen(Qt::black); // default axis line color and width + axisPen.setWidth(1); + + QtCharts::QValueAxis *axisX = NULL; + QtCharts::QCategoryAxis *categoryX = NULL; + if (_showXticks == SHOW_TICK || _showXticks == HIDE_TICK) { + bool add = true; + if (_xAxisBottom) { + axisX = dynamic_cast(_xAxisBottom); + add = false; + } else { + axisX = new QtCharts::QValueAxis; + } + axisX->setGridLineVisible(_enableGrid); + axisX->setTitleText(_xLabel); + axisX->setLinePen(axisPen); + axisX->setRange(_xMin, _xMax); + axisX->setTickCount(_xTickCount); + if (!_customLimits) + axisX->applyNiceNumbers(); + if (add) + _chart->addAxis(axisX, Qt::AlignBottom); + _xAxisBottom = axisX; + if (_showXticks == HIDE_TICK) + axisX->setLabelsVisible(false); + } else if (_showXticks == SHOW_CUSTOM_TICK) { + categoryX = new QtCharts::QCategoryAxis(); + categoryX->setGridLineVisible(_enableGrid); + categoryX->setLinePen(axisPen); + + if (_showXticks && _xTicks.size()) + for (int i = 0; i < _xTicks.size(); i++) { #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "show(): xtick[" << i << "]=(" << _xTicks[i].second << " , " << - _xTicks[i].first << ")"; + qDebug() << "show(): xtick[" << i << "]=(" << _xTicks[i].second + << " , " << _xTicks[i].first << ")"; #endif - categoryX->append(_xTicks[i].first, _xTicks[i].second); - } - - categoryX->setRange(_xMin, _xMax); - categoryX->setTickCount(_xTicks.size()); - if(_xAxisBottom) - _chart->removeAxis(_xAxisBottom); - _chart->addAxis(categoryX, Qt::AlignBottom); - _xAxisBottom = categoryX; + categoryX->append(_xTicks[i].first, _xTicks[i].second); } - QtCharts::QValueAxis* axisY = NULL; - QtCharts::QCategoryAxis* categoryY = NULL; - if (_showYticks == SHOW_TICK || _showYticks == HIDE_TICK) // this is the default ticks setup - { - bool add = true; - if(_yAxisLeft){ - axisY = dynamic_cast(_yAxisLeft); - add = false; - }else{ - axisY = new QtCharts::QValueAxis; - } - - axisY->setGridLineVisible(_enableGrid); - axisY->setTitleText(_yLabel); - axisY->setLinePen(axisPen); - axisY->setRange(_yMin, _yMax); - axisY->setTickCount(_yTickCount); - if (!_customLimits) axisY->applyNiceNumbers(); - if(add) - _chart->addAxis(axisY, Qt::AlignLeft); - _yAxisLeft = axisY; - - if (_showYticks == HIDE_TICK) - axisY->setLabelsVisible(false); - } - else if (_showYticks == SHOW_CUSTOM_TICK) // this is for user defined ticks - { - categoryY = new QtCharts::QCategoryAxis(); - categoryY->setGridLineVisible(_enableGrid); - categoryY->setLinePen(axisPen); - - if (_showYticks && _yTicks.size() > 0) - for (int i = 0; i < _yTicks.size(); i++) - { + categoryX->setRange(_xMin, _xMax); + categoryX->setTickCount(_xTicks.size()); + if (_xAxisBottom) + _chart->removeAxis(_xAxisBottom); + _chart->addAxis(categoryX, Qt::AlignBottom); + _xAxisBottom = categoryX; + } + + QtCharts::QValueAxis *axisY = NULL; + QtCharts::QCategoryAxis *categoryY = NULL; + if (_showYticks == SHOW_TICK || + _showYticks == HIDE_TICK) // this is the default ticks setup + { + bool add = true; + if (_yAxisLeft) { + axisY = dynamic_cast(_yAxisLeft); + add = false; + } else { + axisY = new QtCharts::QValueAxis; + } + + axisY->setGridLineVisible(_enableGrid); + axisY->setTitleText(_yLabel); + axisY->setLinePen(axisPen); + axisY->setRange(_yMin, _yMax); + axisY->setTickCount(_yTickCount); + if (!_customLimits) + axisY->applyNiceNumbers(); + if (add) + _chart->addAxis(axisY, Qt::AlignLeft); + _yAxisLeft = axisY; + + if (_showYticks == HIDE_TICK) + axisY->setLabelsVisible(false); + } else if (_showYticks == + SHOW_CUSTOM_TICK) // this is for user defined ticks + { + categoryY = new QtCharts::QCategoryAxis(); + categoryY->setGridLineVisible(_enableGrid); + categoryY->setLinePen(axisPen); + + if (_showYticks && _yTicks.size() > 0) + for (int i = 0; i < _yTicks.size(); i++) { #if (DEBUG > 1) && (DEBUG < 3) - qDebug() << "show(): ytick[" << i << "]=(" << _yTicks[i].second << " , " << - _yTicks[i].first << ")"; + qDebug() << "show(): ytick[" << i << "]=(" << _yTicks[i].second + << " , " << _yTicks[i].first << ")"; #endif - categoryY->append(_yTicks[i].first, _yTicks[i].second); - } - - categoryY->setRange(_yMin, _yMax); - categoryY->setTickCount(_yTicks.size()); - if(_yAxisLeft) - _chart->removeAxis(_yAxisLeft); - _chart->addAxis(categoryY, Qt::AlignLeft); - _yAxisLeft = categoryY; + categoryY->append(_yTicks[i].first, _yTicks[i].second); } - /* Other possible customizations such as margins and background color */ - // Remove (fat) exterior margins from QChart - _chart->layout()->setContentsMargins(0, 0, 0, 0); - _chart->setBackgroundRoundness(0); - - /* Add series of data */ - _chart->removeAllSeries(); - for(auto itr : _seriesVec) - { - _chart->addSeries(itr.get()); - - if (_showXticks == SHOW_TICK || _showXticks == HIDE_TICK) - { - itr->attachAxis(axisX); - } - else if (_showXticks == SHOW_CUSTOM_TICK) - { - itr->attachAxis(categoryX); - } - - if (_showYticks == SHOW_TICK || _showYticks == HIDE_TICK) - { - itr->attachAxis(axisY); - } - else if (_showYticks == SHOW_CUSTOM_TICK) - { - itr->attachAxis(categoryY); - } - } + categoryY->setRange(_yMin, _yMax); + categoryY->setTickCount(_yTicks.size()); + if (_yAxisLeft) + _chart->removeAxis(_yAxisLeft); + _chart->addAxis(categoryY, Qt::AlignLeft); + _yAxisLeft = categoryY; + } - _chartView->setRenderHint(QPainter::Antialiasing); - _chartView->resize(600, 400); + /* Other possible customizations such as margins and background color */ + // Remove (fat) exterior margins from QChart + _chart->layout()->setContentsMargins(0, 0, 0, 0); + _chart->setBackgroundRoundness(0); + + /* Add series of data */ + _chart->removeAllSeries(); + for (auto itr : _seriesVec) { + _chart->addSeries(itr.get()); + + if (_showXticks == SHOW_TICK || _showXticks == HIDE_TICK) { + itr->attachAxis(axisX); + } else if (_showXticks == SHOW_CUSTOM_TICK) { + itr->attachAxis(categoryX); + } + + if (_showYticks == SHOW_TICK || _showYticks == HIDE_TICK) { + itr->attachAxis(axisY); + } else if (_showYticks == SHOW_CUSTOM_TICK) { + itr->attachAxis(categoryY); + } + } - // Take a screenshot of the widget before it's destroyed - // so it can be saved later, when savefig() is invoked after show(). - + _chartView->setRenderHint(QPainter::Antialiasing); + _chartView->resize(600, 400); - _chartView->show(); + // Take a screenshot of the widget before it's destroyed + // so it can be saved later, when savefig() is invoked after show(). - // This loop blocks execution & waits for the window to be destroyed. - // However, is this chart is supposed to be a real widget, then do none of this. - if (!_isWidget) - { - _pixmap = _chartView->grab(); - _chartView->setAttribute(Qt::WA_DeleteOnClose); // This deletes _chartView! - QEventLoop loop; - QObject::connect(_chartView, SIGNAL(destroyed()), &loop, SLOT(quit())); - loop.exec(); + _chartView->show(); - // _chartView was automatically deleted. Release all the other resources! - //_seriesVec.clear(); - } + // This loop blocks execution & waits for the window to be destroyed. + // However, is this chart is supposed to be a real widget, then do none of + // this. + if (!_isWidget) { + _pixmap = _chartView->grab(); + _chartView->setAttribute( + Qt::WA_DeleteOnClose); // This deletes _chartView! + QEventLoop loop; + QObject::connect(_chartView, SIGNAL(destroyed()), &loop, SLOT(quit())); + loop.exec(); -#if (DEBUG > 0) && (DEBUG < 2) - qDebug() << "show(): -----" ; -#endif + // _chartView was automatically deleted. Release all the other resources! + //_seriesVec.clear(); } - void clear(){ - _seriesVec.clear(); - } +#if (DEBUG > 0) && (DEBUG < 2) + qDebug() << "show(): -----"; +#endif + } + void clear() { _seriesVec.clear(); } private: + bool _is_marker(const QString &cmd) { + if (cmd == "-" || cmd == "--" || cmd == "." || cmd == "o" || cmd == "s") + return true; - bool _is_marker(const QString& cmd) - { - if (cmd == "-" || cmd == "--" || cmd == "." || cmd == "o" || cmd == "s") - return true; + return false; // cmd is a label for the legend + } - return false; // cmd is a label for the legend - } + void _check_cmds_are_good(const QString &cmd1, const QString &cmd2) { + if (_is_marker(cmd1) && !_is_marker(cmd2)) + return; - void _check_cmds_are_good(const QString& cmd1, const QString& cmd2) - { - if (_is_marker(cmd1) && !_is_marker(cmd2)) - return; + if (!_is_marker(cmd1) && _is_marker(cmd2)) + return; - if (!_is_marker(cmd1) && _is_marker(cmd2)) - return; + qCritical() << "_check_cmds_are_good()!!! Only one marker and one label " + "are allowed."; + exit(-1); + } - qCritical() << "_check_cmds_are_good()!!! Only one marker and one label are allowed."; - exit(-1); - } + void _parseLegend() { + if (!_legend.size()) + return; - void _parseLegend() - { - if (!_legend.size()) - return; - - QRegExp equalsRegex("(\\=)"); //RegEx for '=' - QStringList wordList = _legend.split(equalsRegex); - - // step1: trim spaces - for (int i = 0; i < wordList.size(); i++) - wordList[i] = wordList[i].trimmed(); - - // step 2: delete empty strings - QMutableStringListIterator it(wordList); // pass list as argument - while (it.hasNext()) - { - if (!it.next().size()) - it.remove(); - } + QRegExp equalsRegex("(\\=)"); // RegEx for '=' + QStringList wordList = _legend.split(equalsRegex); - int i = -1; - QStringList::iterator iter = std::find(wordList.begin(), wordList.end(), "label"); - if (iter != wordList.end()) - i = iter - wordList.begin(); // if "loc" is in the list, i has the index + // step1: trim spaces + for (int i = 0; i < wordList.size(); i++) + wordList[i] = wordList[i].trimmed(); - // ok, "label" exists && there's another word after it on the list - if (i >= 0 && i+1 < wordList.size()) - _legend = wordList[i+1]; - else - _legend.clear(); + // step 2: delete empty strings + QMutableStringListIterator it(wordList); // pass list as argument + while (it.hasNext()) { + if (!it.next().size()) + it.remove(); } - QString _parseLegendPos(QString cmd) - { - if (!cmd.size()) - return QString(); - - QRegExp equalsRegex("(\\=)"); //RegEx for '=' - QStringList wordList = cmd.split(equalsRegex); - - // step1: trim spaces - for (int i = 0; i < wordList.size(); i++) - wordList[i] = wordList[i].trimmed(); - - // step 2: delete empty strings - QMutableStringListIterator it(wordList); // pass list as argument - while (it.hasNext()) - { - if (!it.next().size()) - it.remove(); - } - - int i = -1; - QStringList::iterator iter = std::find(wordList.begin(), wordList.end(), "loc"); - if (iter != wordList.end()) - i = iter - wordList.begin(); // if "loc" is in the list, i has the index - - // ok, "label" exists && there's another word after it on the list - if (i >= 0 && i+1 < wordList.size()) - return wordList[i+1]; - - return QString(); + int i = -1; + QStringList::iterator iter = + std::find(wordList.begin(), wordList.end(), "label"); + if (iter != wordList.end()) + i = iter - wordList.begin(); // if "loc" is in the list, i has the index + + // ok, "label" exists && there's another word after it on the list + if (i >= 0 && i + 1 < wordList.size()) + _legend = wordList[i + 1]; + else + _legend.clear(); + } + + QString _parseLegendPos(QString cmd) { + if (!cmd.size()) + return QString(); + + QRegExp equalsRegex("(\\=)"); // RegEx for '=' + QStringList wordList = cmd.split(equalsRegex); + + // step1: trim spaces + for (int i = 0; i < wordList.size(); i++) + wordList[i] = wordList[i].trimmed(); + + // step 2: delete empty strings + QMutableStringListIterator it(wordList); // pass list as argument + while (it.hasNext()) { + if (!it.next().size()) + it.remove(); } - QPixmap _pixmap; // show() screenshots the widget, savefig() writes it on the disk - QtCharts::QChart* _chart; // manages the graphical representation of the chart's series, legends & axes - QtCharts::QChartView* _chartView; // standalone widget that can display charts - QMap> _seriesVec; // every plot() creates a new series of data that is stored here - - - bool _isWidget; // true: show() doesn't block so this can be used as widget - QString _legend; - QString _legendPos; - - QVector > _xTicks; // user defined ticks that replace default ticks - QVector > _yTicks; - int _showXticks; // flag that show/hides the exhibition of ticks on the X axis - int _showYticks; // flag that show/hides the exhibition of ticks on the Y axis - int _xTickCount; // number of ticks displayed on the X axis - int _yTickCount; // number of ticks displayed on the Y axis - - QString _title; // Chart title - QString _yLabel; // String that appears to the left of the Y axis - QString _xLabel; // String that appears below the X axis - - QVector _colors; // Vector that stores chart's predefined colours - int _colorIdx; // Every plot() increases this index so the next has a different colour - - bool _customLimits; // If the user has informed new limits through xlim(), ylim(), or axis() - qreal _xMin; // X axis min limit - qreal _xMax; // X axis max limit - qreal _yMin; // Y axis min limit - qreal _yMax; // Y axis max limit - - bool _enableGrid; // flag that show/hides the background grid - QtCharts::QAbstractAxis* _yAxisLeft; - QtCharts::QAbstractAxis* _yAxisRight; - QtCharts::QAbstractAxis* _xAxisBottom; - QtCharts::QAbstractAxis* _xAxisTop; + int i = -1; + QStringList::iterator iter = + std::find(wordList.begin(), wordList.end(), "loc"); + if (iter != wordList.end()) + i = iter - wordList.begin(); // if "loc" is in the list, i has the index + + // ok, "label" exists && there's another word after it on the list + if (i >= 0 && i + 1 < wordList.size()) + return wordList[i + 1]; + + return QString(); + } + + QPixmap + _pixmap; // show() screenshots the widget, savefig() writes it on the disk + QtCharts::QChart *_chart; // manages the graphical representation of the + // chart's series, legends & axes + QtCharts::QChartView *_chartView; // standalone widget that can display charts + QMap> + _seriesVec; // every plot() creates a new series of data that is stored + // here + + bool _isWidget; // true: show() doesn't block so this can be used as widget + QString _legend; + QString _legendPos; + + QVector> _xTicks; // user defined + // ticks that replace default ticks + QVector> _yTicks; + int _showXticks; // flag that show/hides the exhibition of ticks on the X axis + int _showYticks; // flag that show/hides the exhibition of ticks on the Y axis + int _xTickCount; // number of ticks displayed on the X axis + int _yTickCount; // number of ticks displayed on the Y axis + + QString _title; // Chart title + QString _yLabel; // String that appears to the left of the Y axis + QString _xLabel; // String that appears below the X axis + + QVector _colors; // Vector that stores chart's predefined colours + int _colorIdx; // Every plot() increases this index so the next has a + // different colour + + bool _customLimits; // If the user has informed new limits through xlim(), + // ylim(), or axis() + qreal _xMin; // X axis min limit + qreal _xMax; // X axis max limit + qreal _yMin; // Y axis min limit + qreal _yMax; // Y axis max limit + + bool _enableGrid; // flag that show/hides the background grid + QtCharts::QAbstractAxis *_yAxisLeft; + QtCharts::QAbstractAxis *_yAxisRight; + QtCharts::QAbstractAxis *_xAxisBottom; + QtCharts::QAbstractAxis *_xAxisTop; }; diff --git a/eigen_tests.cpp b/eigen_tests.cpp index 9d14ee8..47ee7d5 100644 --- a/eigen_tests.cpp +++ b/eigen_tests.cpp @@ -85,7 +85,7 @@ void test3() plt.title("Test 3: Multiple Data Series"); plt.axis(0, 25, 0, 14); plt.plot(x, y, marker=QString("--"), label=QString("label=Dashed Line")); - plt.plot(x, y+5, label=QString("label=Default Line"), (quint32)4); + plt.plot(x, y+5, label=QString("label=Default Line"), markersize=4); plt.plot(x, y+10, QString("."), label=QString("label=Dotted Line")); plt.legend(); // default position is "lower center" plt.show(); From adbf0ac8a7cae577b88a27d0bb1b3621d122c34a Mon Sep 17 00:00:00 2001 From: Olzhas Adiyatov Date: Sat, 28 Jan 2023 20:50:05 -0500 Subject: [PATCH 9/9] Clean CMakeLists.txt --- CMakeLists.txt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0799324..d8dd138 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,10 @@ cmake_minimum_required(VERSION 3.0) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 14) project(madplotlib) - - -include_directories(${CMAKE_CURRENT_LIST_DIR}) - find_package(Qt5 REQUIRED COMPONENTS Charts) -include_directories(${Qt5_Charts_INCLUDE_DIRS}) - find_package(Eigen3 REQUIRED) add_executable(eigen_test eigen_tests.cpp)