Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PySide6 QtDataVisualization: Q3DSurface Figure Not Showing
QtWS25 Last Chance

PySide6 QtDataVisualization: Q3DSurface Figure Not Showing

Scheduled Pinned Locked Moved Unsolved Qt for Python
pysidepythonqt for python
7 Posts 4 Posters 913 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    ccortez
    wrote on 19 Apr 2022, 17:22 last edited by ccortez
    #1

    Hello, I am trying to create a surface plot with the QDataVisualization QSurface3D library and have been running into some issues.

    Data:
    So, essentially what I am trying to do is get my x, y, and z data to plot a figure using Q3DSurface. I am reading in this data from a file, and converting into into a Pandas dataframe. The values in it consist of numpy.float64 data types. Each of these X, Y , and Z columns are of length 446, 082. The intended figure ends up should end up looking like a cylinder.

    Problem:
    I more more or less tried to follow this example on the qt docs website here. The main issue that I am having is that the figure is not showing up. If you look at my output, you can see that all the axes are filled with values, and all of them are accurate. I cross-validated them with my data log and it seems that they are in the right places and axes. The issue is that no figure is being output on the actual plot itself. There is a shade in it, which leads me to believe that it just didnt finish drawing what is supposed to be there.

    The data is there but I feel like I am missing something crucial that I haven't caught. Maybe the issue is with the drawing or how I am setting the data, but I've been struggling to figure it out. I have tried different formats for surface data item and messing with the data but nothing really seems to work.

    Any ideas, guides, or solutions to this would be appreciated. Thank you.

    Code:

    import sys
    import pandas as pd
    from PySide6.QtGui import QVector3D
    from PySide6.QtWidgets import QApplication, QWidget, QHBoxLayout
    from PySide6.QtCore import QObject
    from PySide6.QtDataVisualization import (
                                             QSurface3DSeries, QSurfaceDataItem,
                                             QSurfaceDataProxy, QValue3DAxis, Q3DSurface)
    
    class Surface(QObject):
        def __init__(self, surface, parent=None):
            QObject.__init__(self, parent)
            self.graph = surface
            self.graph.setAxisX(QValue3DAxis())
            self.graph.setAxisY(QValue3DAxis())
            self.graph.setAxisZ(QValue3DAxis())
    
            self.surfaceproxy = QSurfaceDataProxy()
            self.surfaceseries = QSurface3DSeries(self.surfaceproxy)
            self.create_data()
    
        def create_data(self):
            file = "mydatalog.txt"
            vars = ['X [mm]', 'Y [mm]', 'Z [mm]']
            df1 = pd.read_csv(file, low_memory=False, on_bad_lines='skip', usecols=vars)
            df1 = df1.apply(pd.to_numeric)
            # Each of these are of length, 446082
            x = list(df1['X [mm]'].values) 
            y = list(df1['Y [mm]'].values)
            z = list(df1['Z [mm]'].values)
    
            data_arr = []
            for i, item in enumerate(x):
                row = [QSurfaceDataItem(QVector3D(x[i], y[i], z[i]))]
                data_arr.append(row)
            print(len(data_arr))
            self.surfaceproxy.resetArray(data_arr)
    
        def show_graph(self):
            self.surfaceseries.setDrawMode(QSurface3DSeries.DrawSurface)
            self.surfaceseries.setFlatShadingEnabled(True)
    
            self.graph.addSeries(self.surfaceseries)
            print(self.surfaceseries)
    
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        g = Q3DSurface()
        container = QWidget.createWindowContainer(g)
    
        w = QWidget()
        layout = QHBoxLayout(w)
        layout.addWidget(container, 1)
        w.show()
    
        surf_graph = Surface(g)
        surf_graph.show_graph()
    
        sys.exit(app.exec())
    

    Output:
    ade0cc3f-bd64-4565-afef-c4486db66c3b-image.png

    1 Reply Last reply
    0
    • C Offline
      C Offline
      CristianMaureira
      wrote on 20 Apr 2022, 16:32 last edited by
      #2

      Does the example you tried work? just to rule out a problem with the module and not your code.
      I'm a bit concerned about object lives in your code, mainly this bit:

          data_arr = []
          for i, item in enumerate(x):
              row = [QSurfaceDataItem(QVector3D(x[i], y[i], z[i]))]
              data_arr.append(row)
          print(len(data_arr))
          self.surfaceproxy.resetArray(data_arr)
      

      Are you certain those Items/Vectors are alive and accessible after that function is being called?
      Can you verify that after the last line in your constructor?

      C 1 Reply Last reply 20 Apr 2022, 17:12
      0
      • C CristianMaureira
        20 Apr 2022, 16:32

        Does the example you tried work? just to rule out a problem with the module and not your code.
        I'm a bit concerned about object lives in your code, mainly this bit:

            data_arr = []
            for i, item in enumerate(x):
                row = [QSurfaceDataItem(QVector3D(x[i], y[i], z[i]))]
                data_arr.append(row)
            print(len(data_arr))
            self.surfaceproxy.resetArray(data_arr)
        

        Are you certain those Items/Vectors are alive and accessible after that function is being called?
        Can you verify that after the last line in your constructor?

        C Offline
        C Offline
        ccortez
        wrote on 20 Apr 2022, 17:12 last edited by
        #3

        @CristianMaureira
        Yes, the sample from the website does work perfectly. I copy pasted each of the modules, ran them locally, and produced exactly what that surface example shows.

        As far as what you asked, yes they do seem to be accessible. It also seems like they are being accessed as well, since the image of the plot shows the corresponding data in my data log on each axis.

        My intention in that block of code was to populate a data item with a 3d vector containing the three x, y, z points for a specific index. then adding that into an array that gets passed into the proxy. That proxy gets passed into the series object, and ultimately that's where the drawing of the plot would happen. I tried to follow a similar flow to the example, which can be found under the surfacegraph.py file in the link of the sample.

        It seems like my data makes it into the series, as the right numbers are being displayed on the plot itself. Just not sure why the actual figure never gets drawn.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 20 Apr 2022, 18:22 last edited by
          #4

          Hi,

          What happens if you make data_arr a member of your Surface class ?

          Just a small side note, a Surface object that takes a "surface" parameter that is stored in a variable named graph makes your code harder to reason about.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          C 1 Reply Last reply 20 Apr 2022, 18:49
          0
          • S SGaist
            20 Apr 2022, 18:22

            Hi,

            What happens if you make data_arr a member of your Surface class ?

            Just a small side note, a Surface object that takes a "surface" parameter that is stored in a variable named graph makes your code harder to reason about.

            C Offline
            C Offline
            ccortez
            wrote on 20 Apr 2022, 18:49 last edited by ccortez
            #5

            @SGaist
            Sorry about that, I tried to mimic the example but I can see how that is difficult to read.

            I am not 100% sure how to go about implementing that. According to the Qt Docs, the data types available would be QSurfaceDataProxy and QSurface3DSeries, I don't know what you are referring to exactly. I already turn that array into the data proxy object, which gets passed into series. Could you specify what you mean exactly? Not 100% sure I understand.

            EDIT: I think I get what you meant. You were meaning for me to try doing something like 'self.data_arr = []' initialized in my constructor for the Surface class. This didn't yield any different results.

            F 1 Reply Last reply 21 Apr 2022, 12:16
            0
            • C ccortez
              20 Apr 2022, 18:49

              @SGaist
              Sorry about that, I tried to mimic the example but I can see how that is difficult to read.

              I am not 100% sure how to go about implementing that. According to the Qt Docs, the data types available would be QSurfaceDataProxy and QSurface3DSeries, I don't know what you are referring to exactly. I already turn that array into the data proxy object, which gets passed into series. Could you specify what you mean exactly? Not 100% sure I understand.

              EDIT: I think I get what you meant. You were meaning for me to try doing something like 'self.data_arr = []' initialized in my constructor for the Surface class. This didn't yield any different results.

              F Offline
              F Offline
              friedemannkleint
              wrote on 21 Apr 2022, 12:16 last edited by
              #6

              Have you tried casting to float QVector3D(float(x[]),... ), In https://codereview.qt-project.org/c/pyside/pyside-setup/+/406733 this was necessary.

              C 1 Reply Last reply 21 Apr 2022, 16:07
              0
              • F friedemannkleint
                21 Apr 2022, 12:16

                Have you tried casting to float QVector3D(float(x[]),... ), In https://codereview.qt-project.org/c/pyside/pyside-setup/+/406733 this was necessary.

                C Offline
                C Offline
                ccortez
                wrote on 21 Apr 2022, 16:07 last edited by
                #7

                @friedemannkleint Unfortunately that didn't do much, but thanks for sharing that resource maybe something in there can help me.

                1 Reply Last reply
                0

                3/7

                20 Apr 2022, 17:12

                • Login

                • Login or register to search.
                3 out of 7
                • First post
                  3/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved