@@ -498,6 +498,64 @@ bool plot(const VectorY &y,
498
498
return plot (x, y, " " , keywords);
499
499
}
500
500
501
+ template <typename VectorX, typename VectorY>
502
+ bool loglog (const VectorX &x, const VectorY &y, const std::string &s = " " ,
503
+ const std::map<std::string, std::string> &keywords = {}) {
504
+ detail::_interpreter::get ();
505
+
506
+ // argument for xscale/yscale is only the string "log"
507
+ PyObject *log_arg = PyTuple_New (1 );
508
+ PyObject *pystring = PyString_FromString (" log" );
509
+ PyTuple_SetItem (log_arg, 0 , pystring);
510
+
511
+ // call xscale("log") and yscale("log"), no kwargs needed hence pass NULL,
512
+ // as explained in https://docs.python.org/3/c-api/object.html
513
+ PyObject *res_x = PyObject_Call (
514
+ detail::_interpreter::get ().s_python_function_xscale , log_arg, NULL );
515
+ PyObject *res_y = PyObject_Call (
516
+ detail::_interpreter::get ().s_python_function_yscale , log_arg, NULL );
517
+
518
+ // clean up
519
+ Py_DECREF (log_arg);
520
+
521
+ if (!res_x)
522
+ throw std::runtime_error (" Call to xscale() failed" );
523
+ Py_DECREF (res_x);
524
+
525
+ if (!res_y)
526
+ throw std::runtime_error (" Call to yscale() failed" );
527
+ Py_DECREF (res_y);
528
+
529
+ // call plot, which gets now plotted in doubly logarithmic scale
530
+ return plot (x, y, s, keywords);
531
+ }
532
+
533
+ template <typename VectorX, typename VectorY>
534
+ bool loglog (const VectorX &x, const VectorY &y,
535
+ const std::map<std::string, std::string> &keywords) {
536
+ return loglog (x, y, " " , keywords);
537
+ }
538
+
539
+ template <typename VectorY>
540
+ bool loglog (const VectorY &y, const std::string &s = " " ,
541
+ const std::map<std::string, std::string> &keywords = {}) {
542
+ std::vector<std::size_t > x (y.size ());
543
+ for (std::size_t i = 0 ; i < x.size (); ++i)
544
+ x.at (i) = i + 1 ; // in loglog scale the values shouldn't be zero
545
+
546
+ return loglog (x, y, s, keywords);
547
+ }
548
+
549
+ template <typename VectorY>
550
+ bool loglog (const VectorY &y,
551
+ const std::map<std::string, std::string> &keywords) {
552
+ std::vector<std::size_t > x (y.size ());
553
+ for (std::size_t i = 0 ; i < x.size (); ++i)
554
+ x.at (i) = i + 1 ; // in loglog scale the values shouldn't be zero
555
+
556
+ return loglog (x, y, " " , keywords);
557
+ }
558
+
501
559
template <typename Numeric>
502
560
void plot_surface (const std::vector<::std::vector<Numeric>> &x,
503
561
const std::vector<::std::vector<Numeric>> &y,
@@ -952,56 +1010,6 @@ bool semilogy(const std::vector<NumericX> &x, const std::vector<NumericY> &y,
952
1010
return res;
953
1011
}
954
1012
955
- template <typename ... Args> bool loglog_call (Args... args) {
956
- // argument for xscale/yscale is only the string "log"
957
- PyObject *log_arg = PyTuple_New (1 );
958
- PyObject *pystring = PyString_FromString (" log" );
959
- PyTuple_SetItem (log_arg, 0 , pystring);
960
-
961
- // call xscale("log") and yscale("log"), no kwargs needed hence pass NULL,
962
- // as explained in https://docs.python.org/3/c-api/object.html
963
- PyObject *res_x = PyObject_Call (
964
- detail::_interpreter::get ().s_python_function_xscale , log_arg, NULL );
965
- PyObject *res_y = PyObject_Call (
966
- detail::_interpreter::get ().s_python_function_yscale , log_arg, NULL );
967
-
968
- // clean up
969
- Py_DECREF (log_arg);
970
-
971
- if (!res_x)
972
- throw std::runtime_error (" Call to xscale() failed" );
973
- Py_DECREF (res_x);
974
-
975
- if (!res_y)
976
- throw std::runtime_error (" Call to yscale() failed" );
977
- Py_DECREF (res_y);
978
-
979
- // call plot, which gets now plotted in doubly logarithmic scale
980
- return plot (args...);
981
- }
982
-
983
- template <typename VectorY>
984
- bool loglog (const VectorY &y, const std::string &s = " " ) {
985
- return loglog_call (y, s);
986
- }
987
-
988
- template <typename VectorX, typename VectorY>
989
- bool loglog (const VectorX &x, const VectorY &y, const std::string &s = " " ) {
990
- return loglog_call (x, y, s);
991
- }
992
-
993
- template <typename VectorY>
994
- bool loglog (const VectorY &y,
995
- const std::map<std::string, std::string> &kwargs) {
996
- return loglog_call (y, kwargs);
997
- }
998
-
999
- template <typename VectorX, typename VectorY>
1000
- bool loglog (const VectorX &x, const VectorY &y,
1001
- const std::map<std::string, std::string> &kwargs) {
1002
- return loglog_call (x, y, kwargs);
1003
- }
1004
-
1005
1013
template <typename NumericX, typename NumericY>
1006
1014
bool errorbar (const std::vector<NumericX> &x, const std::vector<NumericY> &y,
1007
1015
const std::vector<NumericX> &yerr,
0 commit comments