c++gnuplotgnuplot-iostream

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:

enter image description here

However, in the plot above, the middle "crater" doesn't actually have any data in it:

enter image description here

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.


Solution

  • 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
    

    enter image description here

    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
    

    enter image description here