Skip to content

Commit

Permalink
tests/visualization-matplotlib-matrix.hh: add support for log plotting
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Chrétien committed Jun 26, 2015
1 parent 511e8fc commit e915061
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 108 deletions.
20 changes: 16 additions & 4 deletions include/roboptim/core/visualization/matplotlib-matrix.hh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ namespace roboptim
/// \addtogroup roboptim_visualization
/// @{

/// \brief Wrap enum for matrix plotting type.
struct MatrixPlotType
{
/// \brief Plotting type for matrices.
enum Type
{
Values,
Log,
Structure
};
};

/// \brief Plot the structure of a matrix with matplotlib.
///
/// Plot the structure of a matrix with matplotlib. Nonzero values will be
Expand All @@ -47,23 +59,23 @@ namespace roboptim
/// and 0 for actual zeros.
///
/// \param mat matrix to plot.
/// \param structureOnly plot only the matrix structure.
/// \param type type of plotting for the matrix.
/// \return Gnuplot command.

ROBOPTIM_DLLAPI
Command plot_mat
(GenericFunctionTraits<EigenMatrixDense>::const_matrix_ref mat,
bool structureOnly = false);
MatrixPlotType::Type type = MatrixPlotType::Values);

ROBOPTIM_DLLAPI
Command plot_mat
(GenericFunctionTraits<EigenMatrixSparse>::const_matrix_ref mat,
bool structureOnly = false);
MatrixPlotType::Type type = MatrixPlotType::Values);

template <typename T>
Command plot_mat
(typename GenericFunctionTraits<T>::const_matrix_ref,
bool /*structureOnly*/ = false)
MatrixPlotType::Type /*type*/ = MatrixPlotType::Values)
{
BOOST_MPL_ASSERT_MSG (false, NOT_IMPLEMENTED, ());
return Command ("");
Expand Down
67 changes: 52 additions & 15 deletions src/visualization/matplotlib-matrix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,35 @@ namespace roboptim
{
namespace detail
{
std::string set_red_to_blue_cmap ()
std::string set_red_white_blue_cmap ()
{
std::stringstream ss;

ss << "cmap = matplotlib.colors.LinearSegmentedColormap.from_list(\n"
<< " name='red_white_blue',\n"
<< " colors =[(0, 0, 1),\n"
<< " (1, 1., 1),\n"
<< " (1, 1, 1),\n"
<< " (1, 0, 0)])\n";

return ss.str ();
}

std::string set_red_yellow_blue_cmap ()
{
std::stringstream ss;

ss << "cmap = matplotlib.colors.LinearSegmentedColormap.from_list(\n"
<< " name='red_yellow_blue',\n"
<< " colors =[(0, 0, 1),\n"
<< " (1, 1, 0),\n"
<< " (1, 0, 0)])\n";

return ss.str ();
}

std::string dense_matrix_to_matplotlib
(GenericFunctionTraits<EigenMatrixDense>::const_matrix_ref mat,
bool structureOnly)
MatrixPlotType::Type type)
{
typedef GenericFunctionTraits<EigenMatrixDense>::matrix_t matrix_t;

Expand All @@ -72,14 +85,26 @@ namespace roboptim

ss << "])" << std::endl;

if (structureOnly)
if (type == MatrixPlotType::Structure)
{
std::string cmap = "matplotlib.colors.ListedColormap(['white', 'blue'])";
ss << "plt.imshow(data > 0, interpolation='nearest', cmap=" << cmap << ")\n";
}
else
else if (type == MatrixPlotType::Log)
{
std::string set_cmap = set_red_to_blue_cmap ();
std::string set_cmap = set_red_yellow_blue_cmap ();
ss << set_cmap
<< "cmap.set_bad('w',1.)\n"
<< "log_data = np.log10(abs(data))\n"
<< "masked_data = np.ma.array (log_data, mask=np.isnan(log_data))\n"
<< "crange = log_data.max()\n"
<< "im = plt.imshow(masked_data, interpolation='nearest', cmap=cmap, vmin=-crange, vmax=crange)\n"
<< "cbar = plt.colorbar(im)\n"
<< "cbar.draw_all()\n";
}
else // values
{
std::string set_cmap = set_red_white_blue_cmap ();
ss << set_cmap
<< "crange = abs(data).max()\n"
<< "im = plt.imshow(data, interpolation='nearest', cmap=cmap, vmin=-crange, vmax=crange)\n"
Expand All @@ -92,7 +117,7 @@ namespace roboptim

std::string sparse_matrix_to_matplotlib
(GenericFunctionTraits<EigenMatrixSparse>::const_matrix_ref mat,
bool structureOnly)
MatrixPlotType::Type type)
{
typedef GenericFunctionTraits<EigenMatrixSparse>::matrix_t matrix_t;

Expand All @@ -109,22 +134,34 @@ namespace roboptim
(StorageOrder == Eigen::RowMajor && it.col () == it.index ()));

double value = 1.;
if (!structureOnly)
if (type != MatrixPlotType::Structure)
value = normalize (it.value ());

ss << (boost::format("data[%i,%i] = %2.8f\n")
% it.row () % it.col () % value).str();
}
}

if (structureOnly)
if (type == MatrixPlotType::Structure)
{
std::string cmap = "matplotlib.colors.ListedColormap(['white', 'blue'])";
ss << "plt.imshow(data, interpolation='nearest', cmap=" << cmap << ")" << std::endl;
}
else
else if (type == MatrixPlotType::Log)
{
std::string set_cmap = set_red_yellow_blue_cmap ();
ss << set_cmap
<< "cmap.set_bad('w',1.)\n"
<< "log_data = np.log10(abs(data))\n"
<< "masked_data = np.ma.array (log_data, mask=np.isnan(log_data))\n"
<< "crange = log_data.max()\n"
<< "im = plt.imshow(masked_data, interpolation='nearest', cmap=cmap, vmin=-crange, vmax=crange)\n"
<< "cbar = plt.colorbar(im)\n"
<< "cbar.draw_all()\n";
}
else // values
{
std::string set_cmap = set_red_to_blue_cmap ();
std::string set_cmap = set_red_white_blue_cmap ();
ss << set_cmap
<< "crange = abs(data).max()\n"
<< "im = plt.imshow(data, interpolation='nearest', cmap=cmap, vmin=-crange, vmax=crange)\n"
Expand All @@ -140,17 +177,17 @@ namespace roboptim

Command plot_mat
(GenericFunctionTraits<EigenMatrixDense>::const_matrix_ref mat,
bool structureOnly)
MatrixPlotType::Type type)
{
return Command (detail::dense_matrix_to_matplotlib (mat, structureOnly), true);
return Command (detail::dense_matrix_to_matplotlib (mat, type), true);
}


Command plot_mat
(GenericFunctionTraits<EigenMatrixSparse>::const_matrix_ref mat,
bool structureOnly)
MatrixPlotType::Type type)
{
return Command (detail::sparse_matrix_to_matplotlib (mat, structureOnly), true);
return Command (detail::sparse_matrix_to_matplotlib (mat, type), true);
}

} // end of namespace matplotlib.
Expand Down
96 changes: 54 additions & 42 deletions tests/visualization-matplotlib-matrix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ struct FortyTwoDense : public DifferentiableFunction
result[4] = argument[2] + argument[4];
result[5] = argument[2] + argument[4];
result[6] = argument[2] + argument[4] + argument[5] + argument[6];
result *= 2.;

for (int i = 0; i < 6; ++i)
{
result[i] *= (value_type)(i+1);
}
}

void impl_gradient (gradient_ref, const_argument_ref, size_type)
Expand All @@ -59,27 +63,27 @@ struct FortyTwoDense : public DifferentiableFunction
const
{
jac.setZero();
jac(0,0) = 2.0;
jac(0,4) = 2.0;
jac(0,5) = 2.0;
jac(0,0) = 1.0;
jac(0,4) = 1.0;
jac(0,5) = 1.0;
jac(1,0) = 2.0;
jac(1,2) = 2.0;
jac(1,6) = 2.0;
jac(2,0) = 2.0;
jac(2,2) = 2.0;
jac(2,6) = 2.0;
jac(3,0) = 2.0;
jac(3,1) = 2.0;
jac(3,2) = 2.0;
jac(3,5) = 2.0;
jac(4,2) = 2.0;
jac(4,4) = 2.0;
jac(5,2) = 2.0;
jac(5,4) = 2.0;
jac(6,2) = 2.0;
jac(6,4) = 2.0;
jac(6,5) = 2.0;
jac(6,6) = 2.0;
jac(2,0) = 3.0;
jac(2,2) = 3.0;
jac(2,6) = 3.0;
jac(3,0) = 4.0;
jac(3,1) = 4.0;
jac(3,2) = 4.0;
jac(3,5) = 4.0;
jac(4,2) = 5.0;
jac(4,4) = 5.0;
jac(5,2) = 6.0;
jac(5,4) = 6.0;
jac(6,2) = 7.0;
jac(6,4) = 7.0;
jac(6,5) = 7.0;
jac(6,6) = 7.0;
}
};

Expand All @@ -102,7 +106,11 @@ struct FortyTwoSparse : public DifferentiableSparseFunction
result[4] = argument[2] + argument[4];
result[5] = argument[2] + argument[4];
result[6] = argument[2] + argument[4] + argument[5] + argument[6];
result *= 2.;

for (int i = 0; i < 6; ++i)
{
result[i] *= (value_type)(i+1);
}
}

void impl_gradient (gradient_ref, const_argument_ref, size_type)
Expand All @@ -114,27 +122,27 @@ struct FortyTwoSparse : public DifferentiableSparseFunction
const
{
jac.setZero();
jac.insert(0,0) = 2.0;
jac.insert(0,4) = 2.0;
jac.insert(0,5) = 2.0;
jac.insert(0,0) = 1.0;
jac.insert(0,4) = 1.0;
jac.insert(0,5) = 1.0;
jac.insert(1,0) = 2.0;
jac.insert(1,2) = 2.0;
jac.insert(1,6) = 2.0;
jac.insert(2,0) = 2.0;
jac.insert(2,2) = 2.0;
jac.insert(2,6) = 2.0;
jac.insert(3,0) = 2.0;
jac.insert(3,1) = 2.0;
jac.insert(3,2) = 2.0;
jac.insert(3,5) = 2.0;
jac.insert(4,2) = 2.0;
jac.insert(4,4) = 2.0;
jac.insert(5,2) = 2.0;
jac.insert(5,4) = 2.0;
jac.insert(6,2) = 2.0;
jac.insert(6,4) = 2.0;
jac.insert(6,5) = 2.0;
jac.insert(6,6) = 2.0;
jac.insert(2,0) = 3.0;
jac.insert(2,2) = 3.0;
jac.insert(2,6) = 3.0;
jac.insert(3,0) = 4.0;
jac.insert(3,1) = 4.0;
jac.insert(3,2) = 4.0;
jac.insert(3,5) = 4.0;
jac.insert(4,2) = 5.0;
jac.insert(4,4) = 5.0;
jac.insert(5,2) = 6.0;
jac.insert(5,4) = 6.0;
jac.insert(6,2) = 7.0;
jac.insert(6,4) = 7.0;
jac.insert(6,5) = 7.0;
jac.insert(6,6) = 7.0;

// To confirm differentiation between structure and value plot
jac.insert(6,0) = 0.;
Expand All @@ -149,7 +157,7 @@ BOOST_AUTO_TEST_CASE (visualization_matplotlib_differentiable_function)
output = retrievePattern("visualization-matplotlib-matrix");

using namespace roboptim::visualization::matplotlib;
Matplotlib matplotlib = Matplotlib::make_matplotlib (std::make_pair (4, 1));
Matplotlib matplotlib = Matplotlib::make_matplotlib (std::make_pair (3, 2));

// Test #1: dense version
FortyTwoDense f_dense;
Expand All @@ -165,12 +173,16 @@ BOOST_AUTO_TEST_CASE (visualization_matplotlib_differentiable_function)
<< (matplotlib
<< comment ("Dense matrix")
<< plot_mat (f_dense.jacobian (arg_dense))
<< comment ("Dense matrix (structure)")
<< plot_mat (f_dense.jacobian (arg_dense), true)
<< comment ("Sparse matrix")
<< plot_mat (f_sparse.jacobian (arg_sparse))
<< comment ("Dense matrix (log)")
<< plot_mat (f_dense.jacobian (arg_dense), MatrixPlotType::Log)
<< comment ("Sparse matrix (log)")
<< plot_mat (f_sparse.jacobian (arg_sparse), MatrixPlotType::Log)
<< comment ("Dense matrix (structure)")
<< plot_mat (f_dense.jacobian (arg_dense), MatrixPlotType::Structure)
<< comment ("Sparse matrix (structure)")
<< plot_mat (f_sparse.jacobian (arg_sparse), true)
<< plot_mat (f_sparse.jacobian (arg_sparse), MatrixPlotType::Structure)
);

std::cout << output->str () << std::endl;
Expand Down
Loading

0 comments on commit e915061

Please sign in to comment.