pbPlots 图形 png 文件不可读 C++

pbPlots graph png file is unreadable C++

我最近在做一个简单的SIR流行病模拟,想用pbPlots来可视化数据。不幸的是,我无法让它正常工作。每次我 运行 我的代码去打开 png 文件时,它只是说该文件不可读或已损坏。我还注意到文件大小只有65字节,比通常的180KB小。

这是我的代码:

/*
    Brandon Pyle
    SIR Epidemic Simulation

    This program is a simple customizable epidemic simulation that uses the SIR model
*/

//Include statements
#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
#include "pbPlots.hpp"
#include "supportLib.hpp"

using namespace std;

//Function prototypes

int main()
{
    //The following block of code creates the title box in the command line
    for (int i = 0; i < 50; i++)
        cout << "*";
    cout << endl << setw(49) << left << "*" << right << "*" << endl;
    cout << "*                  Brandon Pyle                  *" << endl;
    cout << "*            SIR Epidemic Simulation             *";
    cout << endl << setw(49) << left << "*" << right << "*" << endl;
    for (int i = 0; i < 50; i++)
        cout << "*";

    cout << endl << endl;

    //Variable Declarations
    int numDays;
    int population;
    double infectionRate = 0.0002; //Percent of other people a person can infect
    double recoveryRate = 10; //In days

    cout << "Enter the length of the simulation in days: ";
    cin >> numDays;

    cout << endl << "Enter the population number for the simulation: ";
    cin >> population;

    if (population > 5000)
        cout << "WARNING: Numbers greater than 5000 may result in incorrect or inaccurate results." << endl;
    else
        cout << endl;

    vector<double> S(population, 0.0); //Number of Susceptible People
    vector<double> I(population, 0.0); //Number of Infected People
    vector<double> R(population, 0.0); //Number of Removed People
    
    //Creates variables for the X-Axis that are used for pbPlots
    vector<double> xPos;
    for (double i = 0.0; i < numDays; i++)
        xPos.push_back(i);

    I[0] = 1; //Starts the simulation with 6 infected people
    S[0] = population - I[0]; //Initial number of susceptible people
    R[0] = 0; //Initial number of removed people

    RGBABitmapImageReference* imageReference = CreateRGBABitmapImageReference();

    cout << setw(5) << right << "Day";
    cout << setw(13) << right << "Susceptible";
    cout << setw(10) << right << "Infected";
    cout << setw(9) << right << "Removed" << endl;

    for (int i = 0; i < numDays; i++)
    {
        cout << setw(5) << right << i + 1;
        cout << setw(13) << right << fixed << setprecision(0) << S[i];
        cout << setw(10) << right << fixed << setprecision(0) << I[i];
        cout << setw(9) << right << fixed << setprecision(0) << R[i] << endl << endl;

        S[i + 1] = S[i] - infectionRate * S[i] * I[i];
        I[i + 1] = I[i] + infectionRate * S[i] * I[i] - I[i] / recoveryRate;
        R[i + 1] = R[i] + I[i] / recoveryRate;
    }

    ScatterPlotSeries* series = GetDefaultScatterPlotSeriesSettings();
    series->xs = &xPos;
    series->ys = &S;
    series->linearInterpolation = false;
    series->lineType = toVector(L"solid");
    series->color = CreateRGBColor(0, 0, 1);
    
    ScatterPlotSeries* series2 = GetDefaultScatterPlotSeriesSettings();
    series->xs = &xPos;
    series->ys = &I;
    series->linearInterpolation = false;
    series->lineType = toVector(L"solid");
    series->color = CreateRGBColor(0, 1, 0);

    ScatterPlotSeries* series3 = GetDefaultScatterPlotSeriesSettings();
    series->xs = &xPos;
    series->ys = &R;
    series->linearInterpolation = false;
    series->lineType = toVector(L"solid");
    series->color = CreateRGBColor(0, 0, 0);

    ScatterPlotSettings *settings = GetDefaultScatterPlotSettings();
    settings->width = 800;
    settings->height = 480;
    settings->autoBoundaries = true;
    settings->autoPadding = true;
    settings->title = toVector(L"SIR Epidemic Simulation");
    settings->xLabel = toVector(L"Days");
    settings->yLabel = toVector(L"Population");
    settings->scatterPlotSeries->push_back(series);
    settings->scatterPlotSeries->push_back(series2);
    settings->scatterPlotSeries->push_back(series3);

    DrawScatterPlotFromSettings(imageReference, settings);

    //DrawScatterPlot(imageReference, 800, 480, &I, &S);
    
    vector<double>* pngData = ConvertToPNG(imageReference->image);
    WriteToFile(pngData, "SIR_Graph_Test.png");
    DeleteImage(imageReference->image);

    return 0;
}

我已将问题缩小为与 xPos 向量有关的问题,但我无法弄清楚为什么它不起作用。此外,如果您注释掉所有 ScatterPlotSeries 内容并取消注释 DrawScatterPlot(...),该程序确实有效;线。此方法有效,因为它使用 X 轴的 I 向量而不是我的 xPos 向量。

有什么建议吗?

这是最小可重现示例:

//Include statements
#include <vector>
#include "pbPlots.hpp"
#include "supportLib.hpp"

using namespace std;

int main()
{
    vector<double> xPos;
    for (double i = 0.0; i < 200; i++)
        xPos.push_back(i);

    vector<double> yPos;
    for (double i = 0.0; i < 200; i++)
        yPos.push_back(pow(i, 2));

    vector<double> yPos2;
    for (double i = 0.0; i < 200; i++)
        yPos2.push_back(i + 2);

    RGBABitmapImageReference* imageReference = CreateRGBABitmapImageReference();

    ScatterPlotSeries* series = GetDefaultScatterPlotSeriesSettings();
    series->xs = &xPos;
    series->ys = &yPos;
    series->linearInterpolation = false;
    series->lineType = toVector(L"solid");
    series->color = CreateRGBColor(0, 0, 1);

    ScatterPlotSeries* series2 = GetDefaultScatterPlotSeriesSettings();
    series->xs = &xPos;
    series->ys = &yPos2;
    series->linearInterpolation = false;
    series->lineType = toVector(L"solid");
    series->color = CreateRGBColor(0, 1, 0);

    ScatterPlotSettings* settings = GetDefaultScatterPlotSettings();
    settings->width = 800;
    settings->height = 480;
    settings->autoBoundaries = true;
    settings->autoPadding = true;
    settings->title = toVector(L"SIR Epidemic Simulation");
    settings->xLabel = toVector(L"Days");
    settings->yLabel = toVector(L"Population");
    settings->scatterPlotSeries->push_back(series);
    settings->scatterPlotSeries->push_back(series2);

    //Comment out the line below when using the working method
    DrawScatterPlotFromSettings(imageReference, settings);

    //Ucomment the line below to get a working graph
    //DrawScatterPlot(imageReference, 800, 480, &xPos, &yPos);

    vector<double>* pngData = ConvertToPNG(imageReference->image);
    WriteToFile(pngData, "SIR_Graph_Test_2.png");
    DeleteImage(imageReference->image);

    return 0;
}

这是一张图片,比较了正常工作的 PNG(右)和损坏的 PNG(左)

我终于想出了如何让它发挥作用。显然你不能在多个 ScatterPlotSeries 中使用同一个向量,你也不能使用变量来确定向量的长度。显然这是一个糟糕的图书馆,所以我将四处寻找一个新的图书馆。

问题很简单,就是你忘了设置series2的属性。查看上面的原始代码,它两次设置“系列”的属性。如果你第二次把series->改成series2->就可以了。