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->就可以了。
我最近在做一个简单的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->就可以了。