diff --git a/pub/lib/plot.cpp b/pub/lib/plot.cpp
index 51f1343026e0e3c9e02a6bca03dba76ddc660da0..318c7e2ccce8a52092e769f907b89d1ed57bfb29 100644
--- a/pub/lib/plot.cpp
+++ b/pub/lib/plot.cpp
@@ -555,8 +555,8 @@ namespace {
             plot->X.set_limits(xinf, xsup);
         if (!plot->Z.finite())
             plot->Z.set_limits(zlim.front(), zlim.back());
-        if (plot->Y.logflag && !(std::isfinite(yinf) && std::isfinite(ysup)))
-            throw "No nonzero y values";
+        if (!(std::isfinite(yinf) && std::isfinite(ysup)))
+            throw "No valid y values";
         if (!plot->Y.finite())
             plot->Y.set_limits(yinf-1e-4*std::abs(yinf), ysup+1e-4*std::abs(ysup));
         // plot
diff --git a/pub/plot/axis.cpp b/pub/plot/axis.cpp
index 01a50438a7f894c204bbd94d4f634c87480eb7c1..d85e1fb581a0db9b9cee114d7e8c897a1cdb6636 100644
--- a/pub/plot/axis.cpp
+++ b/pub/plot/axis.cpp
@@ -11,6 +11,7 @@
 #include <iomanip>
 #include <iostream>
 #include <vector>
+#include <boost/format.hpp>
 
 #include "../readplus/macro.hpp"
 #include "../trivia/math.hpp"
@@ -21,6 +22,7 @@
 using std::string;
 using std::vector;
 using std::cout;
+using boost::format;
 
 #define S(a) triv::strg((a))
 
@@ -62,7 +64,7 @@ void CAxis::ask_and_set(const string& quest)
 {
     for (;;) {
         double inf_in, sup_in;
-        string resp1 = NMacro::readwd(quest + " [" + str() + "] ? ");
+        string resp1 = NMacro::readwd(quest + " [" + to_s() + "] ? ");
         if (resp1 == "\\q") {
             throw S("user escape to main menu");
         } else if (resp1 == "") {
@@ -82,7 +84,7 @@ void CAxis::ask_and_set(const string& quest)
                     "    0.1  \\      let upper bound unchanged\n"
                     "    *           redetermine bounds from data\n"
                     "just press ENTER to let present range unchanged ["
-                 << str() << "]\n";
+                 << to_s() << "]\n";
             continue;
         }
         if (logflag && inf_in <= 0) {
@@ -277,7 +279,7 @@ void CAxis::set_xgrid(vector<double>& x, int n) const
 
 //! Returns string representation of plot range.
 
-string CAxis::str() const
+string CAxis::to_s() const
 {
     if (inf == -INFINITY || sup == +INFINITY)
         return "*";
@@ -369,7 +371,8 @@ void CAxis::calc_lintacks(vector<double>& Tacks, int& ntpt, double& dtack) const
     double drange = dhig-dlow;
     int nTacks = drange/dtack + 1.5;
     if (nTacks<2)
-        throw "BUG: calc_lintacks -> nTacks<2";
+        throw str(format("BUG in calc_lintacks: nTacks<2 for inf=%g sup=%g dtack=%g low=%g hig=%g")
+                  % inf % sup % dtack % dlow % dhig);
     for (int i=0; i<nTacks; ++i) {
         double d = (i*dhig + (nTacks-1-i)*dlow)/(nTacks-1);
         if (std::abs(d)<1e-15*drange)
diff --git a/pub/plot/axis.hpp b/pub/plot/axis.hpp
index e01fbc45c71b8deff4a01396d168f81b6276b9d9..e4422be3b4567adc0167d6308263555e77475fc3 100644
--- a/pub/plot/axis.hpp
+++ b/pub/plot/axis.hpp
@@ -33,7 +33,7 @@ public:
     void set_rounded_limits(double _inf, double _sup);
     void ask_and_set(const std::string& quest);
 
-    std::string str() const;
+    std::string to_s() const;
     std::string info() const;
     bool finite() const;
     bool contains(double val) const;
diff --git a/pub/plot/ps_plotter.cpp b/pub/plot/ps_plotter.cpp
index caf204fa120e8cef35256f161fccbe4c916da932..1e63ea0ecd605644059d2aa233a7ec95f7820d92 100644
--- a/pub/plot/ps_plotter.cpp
+++ b/pub/plot/ps_plotter.cpp
@@ -205,7 +205,7 @@ namespace {
     {
         string ret = "% " + A->name + " axis:\n";
         if (A->logflag && A->inf <= 0)
-            throw "BUG: log incompatible with limits " + A->str();
+            throw "BUG: log incompatible with limits " + A->to_s();
         ret += ps_ticktack(A);
         return ret;
     }
diff --git a/pub/trivia/vector_ops.cpp b/pub/trivia/vector_ops.cpp
index 49a0d6b6c27a962b103c798dff63a23286debdcd..ed77e9efc9ab24e7003cf3bf8010a46b8622b4d0 100644
--- a/pub/trivia/vector_ops.cpp
+++ b/pub/trivia/vector_ops.cpp
@@ -168,14 +168,32 @@ std::string triv::indices_to_s(const vector<int>& v)
     return ret;
 }
 
+//! Determines minimal and maximal value in vector v.
+//! Results must be tested for finiteness.
+void triv::getMinMax(const std::vector<double>& v, double& minval, double&maxval)
+{
+    if (v.size()==0)
+        throw "BUG: attempt to determine min and max of empty vector";
+    minval = +INFINITY;
+    maxval = -INFINITY;
+    for (auto t = v.begin(); t<v.end(); ++t) {
+        if (!std::isfinite(*t))
+            continue;
+        minval = std::min(minval, *t);
+        maxval = std::max(maxval, *t);
+    }
+}
+
 //! Determines minimal positive value and maximal value in vector v.
 //! Results must be tested for finiteness.
 void triv::getPosminMax(const std::vector<double>& v, double& minval, double&maxval)
 {
+    if (v.size()==0)
+        throw "BUG: attempt to determine min and max of empty vector";
     minval = +INFINITY;
     maxval = -INFINITY;
     for (auto t = v.begin(); t<v.end(); ++t) {
-        if (*t<=0)
+        if (!std::isfinite(*t) || *t<=0)
             continue;
         minval = std::min(minval, *t);
         maxval = std::max(maxval, *t);
diff --git a/pub/trivia/vector_ops.hpp b/pub/trivia/vector_ops.hpp
index b47e28bb9b59d5d8dc138ec66e04e334ed9b89c4..c3f2e2df6250337bc7b17cb07667f5e5c35bf03a 100644
--- a/pub/trivia/vector_ops.hpp
+++ b/pub/trivia/vector_ops.hpp
@@ -25,7 +25,7 @@ namespace triv
     void increment_indices(std::vector<int>& v, int incr, int siz);
     std::string indices_to_s(const std::vector<int>& v);
 
-    template <class T> void getMinMax(const std::vector<T>& v, T& minval, T&maxval);
+    void getMinMax(const std::vector<double>& v, double& minval, double&maxval);
     void getPosminMax(const std::vector<double>& v, double& minval, double&maxval);
     template <class T> bool contains(const std::vector<T>& v, const T e);
     template <class T, class Pred> std::vector<T> merge_sorted(
@@ -35,19 +35,6 @@ namespace triv
 //  Template implementation
 //**************************************************************************************************
 
-    template <class T>
-    void getMinMax(const std::vector<T>& v, T& minval, T&maxval)
-    {
-        if (v.size()==0)
-            throw "BUG: attempt to determine min and max of empty vector";
-        minval = v.front();
-        maxval = v.front();
-        for (auto t = v.begin()+1; t<v.end(); ++t) {
-            minval = std::min(minval, *t);
-            maxval = std::max(maxval, *t);
-        }
-    }
-
     template <class T>
     bool contains(const std::vector<T>& v, const T e)
     {