Skip to content

Commit

Permalink
added bar plots
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien Gacon committed Sep 9, 2016
1 parent d4ff437 commit e0cb3e9
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 2 deletions.
26 changes: 26 additions & 0 deletions src/MglPlot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,5 +145,31 @@ class MglSpy : public MglPlot {
mglData yd_;
};

class MglBarPlot : public MglPlot {
public:
MglBarPlot(const mglData& xd, const mglData& yd, const std::string& style)
: MglPlot(style)
, xd_(xd)
, yd_(yd)
{}

bool is_3d() {
return false;
}

void plot(mglGraph* gr) {
gr->Bars(xd_, yd_, style_.c_str());
// only add the legend-entry if there is one, otherwise we might end up
// with a legend-entry containing the line style but no description
if (legend_.size() > 0) {
gr->AddLegend(legend_.c_str(), style_.c_str());
}
}

private:
mglData xd_;
mglData yd_;
};

} // end namespace
#endif
59 changes: 57 additions & 2 deletions src/figure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ class Figure {

void addlabel(const std::string& label, const std::string& style);

template <typename yVector>
MglPlot& bar(const yVector& y, std::string style = "");

template <typename xVector, typename yVector>
typename std::enable_if<!std::is_same<typename std::remove_pointer<typename std::decay<yVector>::type>::type, char >::value, MglPlot&>::type
bar(const xVector& x, const yVector& y, std::string style = "");

template <typename yVector>
MglPlot& plot(const yVector& y, std::string style = "");

Expand Down Expand Up @@ -137,6 +144,54 @@ class Figure {
std::vector<std::pair<std::string, std::string>> additionalLabels_; // manually added labels
};

/* bar plot for given y data *
* PRE : - *
* POST: add bar plot of [1:length(y)]-y to plot queue with given style (optional) */
template <typename yVector>
MglPlot& Figure::bar(const yVector& y, std::string style)
{
// build a fitting x vector for the y vector
std::vector<double> x(y.size());
std::iota(x.begin(), x.end(), 1);
return bar(x, y, style);
}

/* bar plot of x,y data *
* PRE : - *
* POST: add bar plot of x-y to plot queue with given style (optional) */
template <typename xVector, typename yVector>
// the long template magic expression ensures this function is not called if yVector is a string (which would be allowed as it is a templated argument)
typename std::enable_if<!std::is_same<typename std::remove_pointer<typename std::decay<yVector>::type>::type, char >::value, MglPlot&>::type
Figure::bar(const xVector& x, const yVector& y, std::string style)
{
if (x.size() != y.size()) {
std::cerr << "In function Figure::plot(): Vectors must have same sizes!";
}

// build mglData from the x and y vectors
mglData xd = make_mgldata(x);
mglData yd = make_mgldata(y);

// if the ranges are set to auto set the new ranges
if(autoRanges_){
setRanges(xd, yd, 0.); // the 0 stands no top+bottom margin
}

// check if a style is given,
// if yes: add that style to the style queue and remove it from the style-deque,
// if no : get a new style from the style-deque
if (style.size() == 0) {
style = styles_.get_next();
}
else {
styles_.eliminate(style);
}

// put the x-y data in the plot queue
plots_.emplace_back(std::unique_ptr<MglBarPlot>(new MglBarPlot(xd, yd, style)));
return *plots_.back().get();
}

/* plot y data *
* PRE : - *
* POST: add [1:length(y)]-y to plot queue with given style (optional) */
Expand Down Expand Up @@ -249,7 +304,7 @@ MglPlot& Figure::spy(const Matrix& A, const std::string& style) {
// x for the col-index and y for the row-index
std::vector<double> x, y;

ranges_ = {0, A.cols() + 1, 0, A.rows() + 1};
ranges_ = std::array<double, 4>{0, A.cols() + 1, 0, A.rows() + 1};
for (unsigned i = 0; i < A.rows(); ++i) {
for (unsigned j = 0; j < A.cols(); ++j) {
if (A(i,j) != 0) {
Expand Down Expand Up @@ -296,7 +351,7 @@ MglPlot& Figure::spy(const Eigen::SparseMatrix<Scalar>& A, const std::string& st
// save positions of entries in these vectors
std::vector<double> x, y;

ranges_ = {0, A.cols() + 1, 0, A.rows() + 1};
ranges_ = std::array<double, 4>{0, A.cols() + 1, 0, A.rows() + 1};
// iterate over nonzero entries, using method suggested in Eigen::Sparse documentation
for (unsigned k = 0; k < A.outerSize(); ++k) {
for (typename Eigen::SparseMatrix<Scalar>::InnerIterator it(A, k); it; ++it) {
Expand Down

0 comments on commit e0cb3e9

Please sign in to comment.