# How to create proper netcdf plots like panoply in using vtk and opengl

**URL:** https://discourse.vtk.org/t/how-to-create-proper-netcdf-plots-like-panoply-in-using-vtk-and-opengl/11328
**Category:** Support
**Created:** [April 27, 2023, 1:23pm UTC](https://discourse.vtk.org/t/how-to-create-proper-netcdf-plots-like-panoply-in-using-vtk-and-opengl/11328 "2023-04-27T13:23:00Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Cave1212](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@Cave1212](https://discourse.vtk.org/u/Cave1212)
#### Post date: [April 27, 2023, 1:23pm UTC](https://discourse.vtk.org/t/how-to-create-proper-netcdf-plots-like-panoply-in-using-vtk-and-opengl/11328/1 "2023-04-27T13:23:00Z")

</div>

In opengl how can i create plots like this

 ![Screenshot 2023-04-27 081354](https://discourse.vtk.org/uploads/default/original/2X/0/01becfab9f2854cb0254feda8686aaa572ffccb9.png)  
using this code

```auto
          vtkSmartPointer<vtkNetCDFCFReader> reader = vtkSmartPointer<vtkNetCDFCFReader>::New();
    reader->SetFileName("C:/Users/admin/Desktop/BOLTgui/BOLT/SEAFLUX-OSB-CDR_V02R00_SST_D20210101_C20210530.nc");
    reader->Update();

    vtkDataObject* dataObject = reader->GetOutput();
    vtkDataSet* dataSet = vtkDataSet::SafeDownCast(dataObject);
    vtkPointData* pointData = dataSet->GetPointData();

    vtkDataArray* latArray = pointData->GetArray("lat");
    vtkDataArray* lonArray = pointData->GetArray("lon");
    vtkDataArray* sstArray = pointData->GetArray("sea_surface_temperature");
    vtkDataArray* timeArray = pointData->GetArray("time");

    vtkSmartPointer<vtkContourFilter> contourFilter = vtkSmartPointer<vtkContourFilter>::New();
    contourFilter->SetInputConnection(reader->GetOutputPort());
    contourFilter->SetValue(0, 20); // set iso-value
    contourFilter->Update();

    vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
    lookupTable->SetNumberOfTableValues(256);
    lookupTable->Build();
    lookupTable->SetTableRange(contourFilter->GetOutput()->GetScalarRange());

    vtkSmartPointer<vtkColorTransferFunction> colorTransferFunction = vtkSmartPointer<vtkColorTransferFunction>::New();
    colorTransferFunction->AddRGBPoint(0.0, 0.0, 0.0, 1.0); // blue
    colorTransferFunction->AddRGBPoint(20.0, 0.0, 1.0, 0.0); // green
    colorTransferFunction->AddRGBPoint(40.0, 1.0, 1.0, 0.0); // yellow
    colorTransferFunction->AddRGBPoint(60.0, 1.0, 0.0, 0.0); // red

    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(contourFilter->GetOutputPort());
    mapper->SetLookupTable(lookupTable);
    mapper->UseLookupTableScalarRangeOn();

    mapper->ScalarVisibilityOn();
    mapper->SetScalarModeToUsePointData();
    mapper->SetLookupTable(lookupTable);
    mapper->SetLookupTable(colorTransferFunction);

    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer < vtkRenderer>::New();
    renderer->AddActor(actor);

    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);

    vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);

    sf::WindowHandle handle = window.getSystemHandle();
    renderWindow->SetWindowInfo(reinterpret_cast<char*>(handle));
    interactor->Start();

       // Draw triangles
        glBegin(GL_TRIANGLES);
        glPointSize(0.111f);

        // Calculate scaling factor
        float scalingFactor = 1.0f / 2.111f;

        vtkSmartPointer<vtkDataSet> data = vtkDataSet::SafeDownCast(reader->GetOutput());
        for (vtkIdType i = 0; i < data->GetNumberOfCells(); i++) {
            vtkCell* cell = data->GetCell(i);
            vtkPoints* points = cell->GetPoints();
            double point1[3];
            double point2[3];
            double point3[3];
            points->GetPoint(0, point1);
            points->GetPoint(1, point2);
            points->GetPoint(2, point3);
            // Scale the point coordinates to adjust the size
            glVertex3f(point1[0] * scalingFactor, point1[1] * scalingFactor, point1[2] * scalingFactor);
            glVertex3f(point2[0] * scalingFactor, point2[1] * scalingFactor, point2[2] * scalingFactor);
            glVertex3f(point3[0] * scalingFactor, point3[1] * scalingFactor, point3[2] * scalingFactor);
        }
        glEnd();

```

this is what i currently have

 ![Screenshot 2023-04-27 082157](https://discourse.vtk.org/uploads/default/original/2X/4/49d796bfa955c75f816534b27f8cb3df85b9fc5a.jpeg)

---

<div class="post-metadata">

### Author: ![Paulo\_Carvalho](https://discourse.vtk.org/user_avatar/discourse.vtk.org/paulo_carvalho/32/370_2.png) [@Paulo\_Carvalho](https://discourse.vtk.org/u/Paulo_Carvalho)
#### Post date: [May 3, 2023, 1:11pm UTC](https://discourse.vtk.org/t/how-to-create-proper-netcdf-plots-like-panoply-in-using-vtk-and-opengl/11328/2 "2023-05-03T13:11:15Z")

</div>

Hello,

First step is to project all that 3D XYZ locations to flat XY locations using some projection (e.g. Mercator). It seems your data already has lat/long positions, so you’re halfway to go. Once you have flat XY coordinates, the next step is to plot your data using 2D VTK.

You can refer to this on how to write code to obtain XY Mercator projection from lat/long data:

> <https://stackoverflow.com/questions/14329691/convert-latitude-longitude-point-to-a-pixels-x-y-on-mercator-projection>

If you have XYZ-only data, just convert them to lat/long before projecting:

```cpp
#include <math.h>

double lat = atan2( y / x );
double long = atan2( sqrt( x*x + y*y ) / z );

```

best,

PC

---

<div class="post-metadata">

### Author: ![Cave1212](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@Cave1212](https://discourse.vtk.org/u/Cave1212)
#### Post date: [May 4, 2023, 12:42pm UTC](https://discourse.vtk.org/t/how-to-create-proper-netcdf-plots-like-panoply-in-using-vtk-and-opengl/11328/3 "2023-05-04T12:42:59Z")

</div>

@Paulo_Carvalho thanks for the reply i do have another question how can i extract the colors from a netcdf file to the traingles lilke whats in the panoply example plot for the opengl c++ code

```auto
      glBegin(GL_TRIANGLES);
      glPointSize(0.111f);

      // Calculate scaling factor
      float scalingFactor = 1.0f / 2.111f;

      vtkSmartPointer<vtkDataSet> data = vtkDataSet::SafeDownCast(reader->GetOutput());
      for (vtkIdType i = 0; i < data->GetNumberOfCells(); i++) {
          vtkCell* cell = data->GetCell(i);
          vtkPoints* points = cell->GetPoints();
          double point1[3];
          double point2[3];
          double point3[3];
          points->GetPoint(0, point1);
          points->GetPoint(1, point2);
          points->GetPoint(2, point3);

          double x = point1[0] + point2[0] + point3[0];
          double y = point1[1] + point2[1] + point3[1];
          double z = point1[2] + point2[2] + point3[2];
          double lat = atan2(y, x);
          double lon = atan2(z, sqrt(x * x + y * y));

          // Set the color for the first vertex
          glColor3f(1.0f, 0.0f, 0.0f);
          // Scale the point coordinates to adjust the size
          glVertex3f(point1[0] * scalingFactor, point1[1] * scalingFactor, point1[2] * scalingFactor);
          // Set the color for the second vertex
          glColor3f(0.0f, 1.0f, 0.0f);
          glVertex3f(point2[0] * scalingFactor, point2[1] * scalingFactor, point2[2] * scalingFactor);
          // Set the color for the third vertex
          glColor3f(0.0f, 0.0f, 1.0f);
          glVertex3f(point3[0] * scalingFactor, point3[1] * scalingFactor, point3[2] * scalingFactor);
      }
      glEnd();

```

---

<div class="post-metadata">

### Author: ![Paulo\_Carvalho](https://discourse.vtk.org/user_avatar/discourse.vtk.org/paulo_carvalho/32/370_2.png) [@Paulo\_Carvalho](https://discourse.vtk.org/u/Paulo_Carvalho)
#### Post date: [May 4, 2023, 1:30pm UTC](https://discourse.vtk.org/t/how-to-create-proper-netcdf-plots-like-panoply-in-using-vtk-and-opengl/11328/4 "2023-05-04T13:30:03Z")

</div>

> [@Cave1212](#):
>
> how can i extract the colors from a netcdf file

Do you have the explicit RGB values in the file or a single scalar that has to be mapped to colors through a color table?

---

<div class="post-metadata">

### Author: ![Cave1212](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@Cave1212](https://discourse.vtk.org/u/Cave1212)
#### Post date: [May 4, 2023, 1:40pm UTC](https://discourse.vtk.org/t/how-to-create-proper-netcdf-plots-like-panoply-in-using-vtk-and-opengl/11328/5 "2023-05-04T13:40:13Z")

</div>

@Paulo_Carvalho  
i got this

```auto
  colorTransferFunction->AddRGBPoint(0.0, 0.0, 0.0, 1.0); // blue
    colorTransferFunction->AddRGBPoint(20.0, 0.0, 1.0, 0.0); // green
    colorTransferFunction->AddRGBPoint(40.0, 1.0, 1.0, 0.0); // yellow
    colorTransferFunction->AddRGBPoint(60.0, 1.0, 0.0, 0.0); // red

```

---

<div class="post-metadata">

### Author: ![Paulo\_Carvalho](https://discourse.vtk.org/user_avatar/discourse.vtk.org/paulo_carvalho/32/370_2.png) [@Paulo\_Carvalho](https://discourse.vtk.org/u/Paulo_Carvalho)
#### Post date: [July 20, 2023, 2:14pm UTC](https://discourse.vtk.org/t/how-to-create-proper-netcdf-plots-like-panoply-in-using-vtk-and-opengl/11328/6 "2023-07-20T14:14:50Z")

</div>

I think this needs to be another question.
