Hi, I would like to suggest a small usability improvement to this great library. The setData and addData methods of QCPGraph and QCPCurve take QVector<double> as parameters, like this:

void addData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false)

This means that for other container types than QVector and/or other element types than double the user has to do some sort of conversion at every call site. But do those methods really need to take QVector<double> as parameters?

When looking at the code I found that the QVectors are really just an intermediate step and are copied into QCustomPlot's own internal data containers. All that is used is their size()-method and their index-operator.

If the setData/addData methods were templated like this,

template<class T1, class T2>
void addData(const T1 &keys, const T2 &values, bool alreadySorted=false)

they would work with any container type that has a size() method and operator[], without any changes to the actual implementation. The user doesn't have to care about the templates at all and can now just write code like this:

std::vector<double> x;
std::array<int, 10> y;
plot->graph(0)->addData(x, y);

Advantages:

* Methods can be called with any Qt or STL container
* Works with any data type that converts to double
* Does not break backwards compatibility, still works with QVector<double> just as before

Disadvantages:

* ???