How to draw a plot chart using visual studio c++ - c++

I want to create a plot chart using visual studio with c++ code. The chart should be based on two axis. "x" axis display the time and "y" axis display the array data. array data have 100 elements and one data read in one second. How do I implement the code using any other graph library?

1) checkout and install Microsoft vcpkg to new folder (see 1-step instruction here: https://github.com/Microsoft/vcpkg)
2) vcpkg.exe install plplot from vcpkg folder
3) vcpkg.exe integrate project will give you instruction to add plplot to your MSVC project
4) paste this instruction to the Nuget Console:
5) after you paste and project reloads you can try this code:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cmath>
#include "plplot\plstream.h"
using namespace std;
const int NSIZE = 101;
int main(int argc, char ** argv) {
PLFLT x[NSIZE], y[NSIZE];
PLFLT xmin = 0., xmax = 1., ymin = 0., ymax = 100.;
int i;
for (i = 0; i < NSIZE; i++) {
x[i] = (PLFLT)(i) / (PLFLT)(NSIZE - 1);
y[i] = ymax * x[i] * x[i];
}
auto pls = new plstream();
plsdev("wingcc");
pls->init();
pls->env(xmin, xmax, ymin, ymax, 0, 0);
pls->lab("x", "y=100 x#u2#d", "Simple PLplot demo of a 2D line plot");
pls->line(NSIZE, x, y);
delete pls;
}
and you get:
tested on MSVC2015

I answered a very similar question a few years ago... there's a simple, straight and compilable example:
Graphical representation - Data Distribution
Obviously, the chart is not the same one that you need. But you can modify it in order to draw anything you want using C++ and then make any chart.

Plotting is a little bit tricky job in C++, as there is no default plotting library available in any C++ IDE. However, there are many libraries available online for making plotting possible in C++. Some plotting tools like Gnuplot, PPlot, Matlab, Python, KoolPlot (May be enough for your requirement).
I have answered a similar question a few days (plotting package for c++). The answer may be helpful.

Related

Plot Contour with Gaps in GNUPlot C++? (C++ 14, VS 22)

I'm attempting to plot a contour plot in the GNUPlot C++ library, however I want to be able to plot with holes in the data (without interpolation where there's no data).
I'm using C++ 14, with Visual Studio 2022.
I have the following example code:
#include <iostream>
#include <string>
#include <vector>
#include "gnuplot-iostream.h"
using namespace std;
int main()
{
vector<vector<float>> data = {};
for (float x = -5; x <= 5; x += 0.1)
{
for (float y = -5; y <= 5; y += 0.1)
{
float dist = sqrt(pow(x, 2) + pow(y, 2));
float z = 1 / dist;
if ((dist > 0.1) && (z < 0.45))
data.push_back(vector<float>{x, y, z});
}
}
Gnuplot gp;
gp << "set title 'test'\n";
gp << "set dgrid3d 100,100\n";
gp << "splot" << gp.file1d(data) << "with pm3d title 'test'" << endl;
cin.get();
return 0;
}
Which produces the following contour plot:
However, in the plot above, the middle "crater" doesn't actually have any data in it:
The function automatically interpolates any areas without data to create the contour plot.
Is it possible in any way to stop that from happening with the contour functions? So the GNUPlot contour functions leave any areas without data empty, instead of interpolating?
Currently I'm using the dgrid3d function to create my contour grid, however it does not appear to be possible to achieve my goal with that. Is there a different graphing function that would be better suited to what I'm trying to accomplish?
Thanks for reading my post, any guidance is appreciated.
First a comment that "contour plot" means something else entirely to gnuplot. There are no contours in this plot.
The issue here is that by setting dgrid3d you reconstruct the full grid with no hole in it. Don't do that. You are generating the data as a grid anyhow, it's just that some of the grid points have a special status. Here are two ways to do it in gnuplot directly. Note that dgrid3d is not used for either method. I don't know anything about iostream so I leave that layer of coding to you.
Method 1 -
Write NaN ("not-a-number") for the points to be omitted.
set samples 101,101
set isosamples 101,101
set urange [-5:5]
set vrange [-5:5]
dist(x,y) = sqrt(x**2 + y**2)
z(x,y) = 1/dist(x,y)
splot '++' using (dist($1,$2)>0.1 && z($1,$2)<0.45 ? $1 : NaN):2:(z($1,$2)) with pm3d
Method 2 -
Write the z value for all points but tell gnuplot to clip at z=0.45
set samples 101,101
set isosamples 101,101
set urange [-5:5]
set vrange [-5:5]
dist(x,y) = sqrt(x**2 + y**2)
z(x,y) = 1/dist(x,y)
set zrange [*:0.45]
splot '++' using 1:2:(z($1,$2)) with pm3d

Removing geometrical objects from geomview window when used in CGAL

I am interested in implementing my computational geometry algorithms using the CGAL library.
Ideally, I am also interested in being able to animate my algorithm.CGAL has an interface to geomview built in which I am interested in using for illustrating these algorithms.
Based on what I little I understand of the CGAL geomview interface (from this example), below is a very simple code I wrote, which inserts 5 random points, and segments between some of the points.
However, once I render the objects to the screen, I don't know how unrender them or delete them from the geomview window, if they need to be deleted at the
next iteration(say) of my algorithm. So how would I modify the code below to do just that?
If someone knows of a better way than using geomview to animate geometry algorithms with CGAL that would also be helpful.
#include <iostream>
#include <vector>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <unistd.h>
#include <CGAL/IO/Geomview_stream.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;
typedef K::Segment_2 Segment_2;
using namespace std;
int main(int argc, char *argv[])
{
Point_2 points[5] = { Point_2(0.,0.), Point_2(10.,0.),Point_2(10.,10.),Point_2(6.,5.),Point_2(4.,1.) };
CGAL::Geomview_stream gv(CGAL::Bbox_3(-12, -12, -0.1, 12,12,0.1));
gv << CGAL::RED; // red points
for (int i = 0; i <= 2; ++i)
{
gv << points[i];
}
gv << CGAL::BLUE;// bluepoints
for (int i = 3; i <= 4; ++i)
{
gv << points[i];
}
// segments between some points
gv << CGAL::BLACK;
Segment_2 AB = Segment_2(points[0],points[1]);
gv << CGAL::YELLOW << AB ;
Segment_2 CD = Segment_2(points[1],points[2]);
gv << CGAL::BLUE << CD ;
sleep(300);
return 0;
}
The current trend among CGAL developers is to use Qt framework and associated visualisation tools such as QGLViewer rather than Geomview which are more recent, fully portative and allows you to do much more (especially if you want to make a demo for your algorithms with user interactions).
If you want to do 3D visualisation with CGAL I will advise you to use QGLViewer as they are already a lot of demos in CGAL that uses that library. For instance as an entry point, I will suggest you to have a look to Alpha_shape_3 demo. The code of this demo is quite light and straightforward, you can easily add new features without understanding the whole Qt framework first (you may have to eventually but that way the learning curve will be less steep and you can quickly start implementing stuff).
If you want to do 2D visualisation, you may have a look to the Alpha_shape_2 demo and use QPainter from Qt (note that you can combine both 3d and 2d viewer in QGL viewer as shown in this example.

How to compute 2D log-chromaticity?

My goal is to remove shadows from image. I use C++ and OpenCV. Sure I lack enough math background and not being native English speaker makes everything harder to understand.
After reading different approaches to remove shadows I found method which should work for me but it relies on something they call "2D chromaticity" and "2D log-chromaticity space" but even this term seems to be inconsistent in different sources. Many papers on topic, few are listed here:
http://www.cs.cmu.edu/~efros/courses/LBMV09/Papers/finlayson-eccv-04.pdf
http://www2.cmp.uea.ac.uk/Research/compvis/Papers/DrewFinHor_ICCV03.pdf
http://www.cvc.uab.es/adas/publications/alvarez_2008.pdf
http://ivrgwww.epfl.ch/alumni/fredemba/papers/FFICPR06.pdf
I teared Google into strips by searching right words and explanations. Best I found is Illumination invariant image which did not help me much.
I tried to repeat formula log(G/R), log(B/R) described in first paper, page 3 to get figures similar to 2b.
As input I used http://en.wikipedia.org/wiki/File:Gretag-Macbeth_ColorChecker.jpg
Output I get is
My source code:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main( int argc, char** argv ) {
Mat src;
src = imread( argv[1], 1 );
if( !src.data )
{ return -1; }
Mat image( 600, 600, CV_8UC3, Scalar(127,127,127) );
int cn = src.channels();
uint8_t* pixelPtr = (uint8_t*)src.data;
for(int i=0 ; i< src.rows;i++) {
for(int j=0 ; j< src.cols;j++) {
Scalar_<uint8_t> bgrPixel;
bgrPixel.val[0] = pixelPtr[i*src.cols*cn + j*cn + 0]; // B
bgrPixel.val[1] = pixelPtr[i*src.cols*cn + j*cn + 1]; // G
bgrPixel.val[2] = pixelPtr[i*src.cols*cn + j*cn + 2]; // R
if(bgrPixel.val[2] !=0 ) { // avoid division by zero
float a= image.cols/2+50*(log((float)bgrPixel.val[0] / (float)bgrPixel.val[2])) ;
float b= image.rows/2+50*(log((float)bgrPixel.val[1] / (float)bgrPixel.val[2])) ;
if(!isinf(a) && !isinf(b))
image.at<Vec3b>(a,b)=Vec3b(255,2,3);
}
}
}
imshow("log-chroma", image );
imwrite("log-chroma.png", image );
waitKey(0);
}
What I am missing or misunderstand?
By reading the paper Recovery of Chromaticity Image Free from Shadows via Illumination Invariance that you've posted, and your code, I guess the problem is that your coordinate system (X/Y axis) are linear while in the paper the coordinate system are log(R/G) by log(B/G).
This is the closest I can figure. Reading through this:
http://www2.cmp.uea.ac.uk/Research/compvis/Papers/DrewFinHor_ICCV03.pdf
I came across the sentence:
"Fig. 2(a) shows log-chromaticities for the 24 surfaces of a Macbeth ColorChecker Chart, (the six neutral patches all belong to the same
cluster). If we now vary the lighting and plot median values
for each patch, we see the curves in Fig. 2(b)."
If you look closely at the log-chromaticity plot, you see 19 blobs, corresponding to each of the 18 colors in the Macbeth chart, plus the sum of all the 6 grayscale targets in the bottom row:
Explanation of Log Chromaticities
Explanation of Log Chromaticities
With 1 picture, we can only get 1 point of each blob: We take the median value inside each target and plot it. To get plot from the paper, we would have to create multiple images with different lighting. We might be able to do this by varying the temperature of the image in an image editor.
For now, I just looked at the color patches in the original image and plotted the points:
Input:
Color Patches Used
Output:
Log Chromaticity
The graph dots are not all in the same place as the paper, but I figure it's fairly close. Would someone please check my work to see if this makes sense?
In that OpenCV code I got a "undefined Identifier error" for the function ifinf() and I solved it by replacing it with _finite(). That might be the issue with the Visual studio version.
if(!isinf(a) && !isinf(b)) ----> if(_finite(a) && _finite(b))
Include this header:
#include<float.h>

libfixmath's atan2 seems to produce invalid results - any ideas, suggestions or alternatives?

I want to do fixed point math in C++, so I looked for a suitable library. libfixmath has been suggested here a couple of times, but I have difficulties with the atan2 function it provides. My test code calculates sine and cosine of an angle and then recalculates that angle using atan2:
#include <cmath>
#include <fstream>
#include <iostream>
#include <fix16.h>
#include <fix16.hpp>
int main()
{
unsigned int n = 1000;
std::ofstream atan2File("atan2.dat");
for(unsigned int i = 0; i <= n; i++)
{
double d = M_PI/2.*i/n;
double s = sin(d);
double c = cos(d);
double a = atan2(s,c);
Fix16 df(d);
Fix16 sf(df.sin());
Fix16 cf(df.cos());
Fix16 af(sf.atan2(cf));
atan2File << d
<< " " << a
<< " " << (double)af
<< std::endl;
}
return 0;
}
Here is the plotted result:
It was generated with gnuplot using
plot "atan2.dat" u 1:2 w l title 'double', "atan2.dat" u 1:3 w l title 'Fix16'
Some values near zero and pi/2 are reasonable, but a lot are not. The code seems to use this algorithm for calculating atan2, but I couldn't spot where it might fail in the way shown above.
Does anyone know of a possible bug in the libfixmath code?
Is there an alternative library that provides trigonometric functions for fixed point values? I need sine, cosine, tangent and their inverse.
I could, of course, try to add the missing functions to other suggested fixed point libraries, but I don't have any experience in writing code for fixed point types.
gcc -v: gcc version 4.7.2 20130108 [gcc-4_7-branch revision 195012] (SUSE Linux)
I need fixed point because I want to do these calculations on a Cortex-M4 (no FPU). Actually I already had libfixmath in my Cortex-M4 code, but it has shown errors like those described above. OTOH, it was about 10 times as fast as the float version. I'd like to add more or less correct results to that speed.

How to draw a QR code with Qt in native C/C++

QR in Qt
As a companion question to How to scan for QR codes with Qt, I want to know how to draw a QR code from native C/C++ code in my Qt5 based desktop app, but I could not find an example of how to do this.
I know QtQR exists, but it has dependencies on python-qrtools which in my opinion kind of defeats the purpose of using Qt in the first place. I want a nimble, efficient and dependency-free solution that will compile with my app wherever I decided to take it.
How can I do that?
UPDATE 3/3-2016: It has come to my attention that there is a small library project that does what my answer does but in a more "prepackaged" way. You can check it out here.
QR in Qt
There is a small QR-code generator library in pure C and without dependencies, called libqrencode.
Step 1: Install
Before you can use it, you will have to install it. On my Ubuntu 13.10 that meant typing the following in a shell:
sudo aptitude install libqrencode-dev
On other platforms you may have to build it from source by yourself. Simply download the tarball and follow the instructions from the source code download.
Step 2: Project file
Next, you will have to add the library to your project. In my Qt5.2.0 project file (myproject.pro or similar) that meant appending the following line:
LIBS += -lqrencode
This should be similar for most versions of Qt that I know.
Step 3: encode
Next one must write the code that actually uses the library to encode some input string to QR format. That is one line of code:
QRcode *qr=QRcode_encodeString("my string", 1, QR_ECLEVEL_L, QR_MODE_8,0);
NOTE: After experimenting with the parameters I have passed to this function, I have learned that one needs to be careful. Some combinations of parameters failed for no good reason. For example passing 0 as version or using QR_MODE_AN failed with "Invalid parameters". This might be bugs in the ancient version of the library that I am using You have been warned.
Step 4: render image
Finally, before cleaning up, you need to convert the output to bitmap so that it can be rendered on the screen. This is simpler than it sounds. Instead of listing a bunch of assumptions I will instead included my complete working minimalistic QRWidget implementation here. The interesting bits are in the overridden paintEvent() method.
QRWidget.hpp
#ifndef QRWIDGET_HPP
#define QRWIDGET_HPP
#include <QWidget>
class QRWidget : public QWidget{
Q_OBJECT
private:
QString data;
public:
explicit QRWidget(QWidget *parent = 0);
void setQRData(QString data);
protected:
void paintEvent(QPaintEvent *);
};
#endif // QRWIDGET_HPP
QRWidget.cpp
#include "QRWidget.hpp"
#include <QPainter>
#include <QDebug>
#include <qrencode.h>
QRWidget::QRWidget(QWidget *parent) :
QWidget(parent),
data("Hello QR")//Note: The encoding fails with empty string so I just default to something else. Use the setQRData() call to change this.
{
}
void QRWidget::setQRData(QString data){
this->data=data;
update();
}
void QRWidget::paintEvent(QPaintEvent *pe){
QPainter painter(this);
//NOTE: I have hardcoded some parameters here that would make more sense as variables.
QRcode *qr = QRcode_encodeString(data.toStdString().c_str(), 1, QR_ECLEVEL_L, QR_MODE_8, 0);
if(0!=qr){
QColor fg("black");
QColor bg("white");
painter.setBrush(bg);
painter.setPen(Qt::NoPen);
painter.drawRect(0,0,width(),height());
painter.setBrush(fg);
const int s=qr->width>0?qr->width:1;
const double w=width();
const double h=height();
const double aspect=w/h;
const double scale=((aspect>1.0)?h:w)/s;
for(int y=0;y<s;y++){
const int yy=y*s;
for(int x=0;x<s;x++){
const int xx=yy+x;
const unsigned char b=qr->data[xx];
if(b &0x01){
const double rx1=x*scale, ry1=y*scale;
QRectF r(rx1, ry1, scale, scale);
painter.drawRects(&r,1);
}
}
}
QRcode_free(qr);
}
else{
QColor error("red");
painter.setBrush(error);
painter.drawRect(0,0,width(),height());
qDebug()<<"QR FAIL: "<< strerror(errno);
}
qr=0;
}
Summary
In this little post I have summarized my experience with getting a QR code generator working with Qt.
If you feel that Fukuchi's library is too large[0] for you, consider looking at Nayuki's C++ QR Code generator library[1]: https://github.com/nayuki/QR-Code-generator/tree/master/cpp
Nayuki's library requires C++11, and is portable without needing Autotools. Sample usage:
#include <string>
#include <vector>
#include "QrCode.hpp"
using namespace qrcodegen;
// Create the QR Code object
QrCode qr = QrCode::encodeText("Hello, world!", QrCode::Ecc::MEDIUM);
// Read the black & white pixels
for (int y = 0; y < qr.size; y++) {
for (int x = 0; x < qr.size; x++) {
int color = qr.getModule(x, y); // 0 for white, 1 for black
// You need to modify this part
draw_pixel_onto_QT(x, y, color);
}
}
[0]: Fukuchi: 20 files, ~7200 lines among the main .c and .h files (excluding build and test code).
[1]: Nayuki: 6 files, ~1400 lines among the main .cpp and .hpp files (excluding demo code).
EDIT 2016-12-08 by OP
I decided, with permission, to add my own adaption to Qt. This code compiles and runs fine on my system, And I think it should be independent enough to work elsewhere without too many tweaks as well.
#include "QrCode.hpp"
void paintQR(QPainter &painter, const QSize sz, const QString &data, QColor fg)
{
// NOTE: At this point you will use the API to get the encoding and format you want, instead of my hardcoded stuff:
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(data.toUtf8().constData(), qrcodegen::QrCode::Ecc::LOW);
const int s=qr.getSize()>0?qr.getSize():1;
const double w=sz.width();
const double h=sz.height();
const double aspect=w/h;
const double size=((aspect>1.0)?h:w);
const double scale=size/(s+2);
// NOTE: For performance reasons my implementation only draws the foreground parts in supplied color.
// It expects background to be prepared already (in white or whatever is preferred).
painter.setPen(Qt::NoPen);
painter.setBrush(fg);
for(int y=0; y<s; y++) {
for(int x=0; x<s; x++) {
const int color=qr.getModule(x, y); // 0 for white, 1 for black
if(0!=color) {
const double rx1=(x+1)*scale, ry1=(y+1)*scale;
QRectF r(rx1, ry1, scale, scale);
painter.drawRects(&r,1);
}
}
}
}
For usage, please see this painter class.
The following is Qt code I used to update a label (qrCode) on a form with the QR code for "text". The label is set to a fixed size (min and max width and height=256 in my case), and scaledContents true. You might do something more efficient than the RGB32 format, but it really shouldn't matter for occasional updates.
void MyClass::updateQrCode( QString text )
{ using namespace qrcodegen;
// Create the QR Code object
QrCode qr = QrCode::encodeText( text.toUtf8().data(), QrCode::Ecc::MEDIUM );
qint32 sz = qr.getSize();
QImage im(sz,sz, QImage::Format_RGB32);
QRgb black = qRgb( 0, 0, 0);
QRgb white = qRgb(255,255,255);
for (int y = 0; y < sz; y++)
for (int x = 0; x < sz; x++)
im.setPixel(x,y,qr.getModule(x, y) ? black : white );
ui->qrCode->setPixmap( QPixmap::fromImage(im.scaled(256,256,Qt::KeepAspectRatio,Qt::FastTransformation),Qt::MonoOnly) );
}
using the Nayuki library - just the QrCode.cpp and .hpp files from here: https://github.com/nayuki/QR-Code-generator/tree/master/cpp
incorporated in my project with this trivial .pri file (kept in the same folder as the QrCode files):
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
HEADERS += $$PWD/QrCode.hpp
SOURCES += $$PWD/QrCode.cpp