从值数组创建直方图/绘图

Creating a Histogram / Plot from an Array of Values

本文关键字:绘图 直方图 创建 数组      更新时间:2023-10-16

我正在尝试创建一个光线分布的图。我想做这个问题的第一步所要求的:对钟形(高斯)曲线进行统计分析。

现在我有一个值数组。我想让数组元素的索引号在图形的x轴上,而存储在索引上的实际值在y轴上。我试图使用OpenCV做到这一点,但OpenCV的直方图函数似乎只绘制值的频率,而不是其他。

我发现cvplot很有用,虽然非常有限:http://code.google.com/p/cvplot/

从c++中嵌入python和提供matplotlib命令也相当容易。我已经用它来产生漂亮的图形,你肯定不会得到从cvplot。下面是一个简单的类,后面是一个示例,但是没有文档(当然,matplotlib有一堆文档):

// Interface to Python's Matplotlib
#include <Python.h>     
using namespace std;
class PyPlot
{
private:
    // Singleton Constructor
    PyPlot() : locked(false)
    {
        Py_SetProgramName("argv[0]");  /* optional but recommended */
        Py_Initialize();
        PyRun_SimpleString(
            "import numpy as npn"
            "import matplotlib.pyplot as pltn"
            "import matplotlib.text as textn"
            "import matplotlib as mpln"
            );
    }
    ~PyPlot()
    {
        Py_Finalize();
    }

    // prevent copies of singleton
    PyPlot(PyPlot const&);    // No  implemention
    void operator=(PyPlot const&); // No implemention

    string to_string(double dval)
    {  
        return std::to_string(long double(dval));
    }
    string to_string(int ival)
    {      
        return std::to_string(long long(ival));
    }

public:
    // get singleton instance
    static PyPlot& getInstance()
    {
        static PyPlot    instance; // Guaranteed to be destroyed.
        // Instantiated on first use.
        return instance;
    }
    // prevent reentry to Matplotlib's show()
    bool locked;

    inline void print_time()
    {
        PyRun_SimpleString("from time import time,ctimen"
                     "print 'Today is',ctime(time())n");
    }
    inline void exec(string command)
    {
        PyRun_SimpleString(command.c_str());
    }
    inline void show()
    {
        locked = true;
        exec("plt.show()n");
        locked = false;
    }
    inline void title(string s, string args = "")
    {
        string command = "plt.title(r'" + s + "'";
        if(args.length() != 0)
            command += ", " + args;
        command += ")n";
        exec(command);
    }
    inline void xlabel(string s, string args = "")
    {
        string command = "plt.xlabel(r'" + s + "'";
        if(args.length() != 0)
            command += ", " + args;
        command += ")n";
        exec(command);
    }
    inline void ylabel(string s, string args = "")
    {
        string command = "plt.ylabel(r'" + s + "'";
        if(args.length() != 0)
            command += ", " + args;
        command += ")n";
        exec(command);
    }
    inline void legend(string args = "")
    {
        string command = "plt.legend(";
        if(args.length() != 0)
            command += args;
        command += ")n";
        exec(command);
    }
    template <typename T>
    inline void define_vector(string name, vector<T> values)
    {
           string command = name + " = [";
           vector<T>::iterator it;
           for(it = values.begin(); it != values.end(); it++)
           {
               command += to_string(*it);
               if(it + 1 != values.end())
                   command += ", ";
           }
           command += "]n";
           exec(command);
    }
    template <typename T>
    inline void plot(vector<T> x, vector<T> y, string args = "")
    {
        define_vector("x", x);
        define_vector("y", y);
        string command = "plt.plot(x, y";
        if(args.length() != 0)
            command += ", " + args;
        command += ")n";
        exec(command);
    }
    template <typename T>
    inline void plot(vector<T> y, string args = "")
    {
        define_vector("y", y);
        vector<int> x;
        for(unsigned int i = 0; i < y.size(); i ++)
            x.push_back(i);
        define_vector("x", x);
        string command = "plt.plot(x, y";
        if(args.length() != 0)
            command += ", " + args;
        command += ")n";
        exec(command);
    }
    inline void example()
    {
        double xa[] = {0.5,   0.7,   0.9 ,   1.3 ,   1.7 ,   1.8};
        vector<double> x;
        x.assign(xa, xa + 6);
        double ya[] = {0.1 ,   0.2 ,   0.75 ,   1.5 ,   2.1 ,   2.4};
        vector<double> y;
        y.assign(ya, ya + 6);
        plot(x, y);
        plot(x, y, "'go', markersize=20");
        exec(
            "plt.xticks( np.arange(0,3) )n"
            "plt.yticks( np.arange(0,2.5,0.2) )n"
            );
        xlabel("x axis");
        ylabel("y axis");
        title("My Plot Example");
        show();
    }
};
#endif

然后像这样使用:

PyPlot &plt = PyPlot::getInstance();
std::vector<int> values;
plt.exec("mpl.rcParams['font.family']='Times New Roman'n"
         "mpl.rcParams['lines.linewidth'] = 2n"
            "mpl.rcParams['axes.linewidth'] = 3n"
            "mpl.rc('xtick', labelsize=12)n"
            "mpl.rc('ytick', labelsize=12)n"
            "ax = plt.gca()n"
            "ax.set_ylim(0, 100)n"
            );
plt.plot(values, "'go-', label='values'");
plt.ylabel("Value", "fontsize=14");
plt.xlabel("Index", "fontsize=14");
plt.show();

这里有创建直方图所需的matplotlib命令:http://matplotlib.org/examples/api/histogram_demo.html

当然你需要安装Python。Python 2.7.3/Win 7/VS2010/OpenCV 2.4.4