Using a graph in a Panda3D window

I am a Junior in high school who has volunteered to make a program for NASA, in a competition called HUNCH. I will try to spare the details, because I feel that a proper description would be a lengthy one. But put simply, I am making a simulation that takes variables (etc. mass, initial velocity), to predict if a Lunar Supply Pod would survive a direct impact to the surface of the moon. What I want to do, is put a graph into the main Panda3D display, to illustrate the trajectory of the object towards the moon.

So here is the problem: Currently, I have my program set up to take inputs, and then trace the route taken by the pod-on the way to the surface, using Matplotlib. Unfortunately, it seems that there is no way to put the graph into the same window as the one that displays the simulation. It is difficult to describe, so I made a picture displaying the ideal end result. So this is my question: how can you display a graph in the main Panda3d window?

Hmm… I don’t know Matplotlib, but if there’s a way to get an image or texture out of it, that could perhaps be applied to a card (that is, a quad) in Panda and thus rendered.

Where would I find an example of cards being used?

This manual page has information on the basic usage of cards, I believe.

Hi, welcome to the forums!

To get it into a Panda3D Texture object, you can create a Texture with the right dimensions, format and component type, and then you can call setRamImage(img, "RGB") where img is some type of byte buffer object that other imaging libraries usually have a way to obtain raw image data in.

Then you can apply the texture to a card, or something like that.

This was a similar question:

Panda is easily embedded in WX Python, as far as I know you can display the contents of Matplotlib in WX Python, I think it is possible to combine. Example: https://stackoverflow.com/questions/10737459/embedding-a-matplotlib-figure-inside-a-wxpython-panel

1 Like

I got it! I used wxpython to combine the display with panda3D. Here is the code:

import wx
import matplotlib
import panda3d.core as core
from direct.showbase.ShowBase import ShowBase
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure

matplotlib.use('WXAgg')

class CanvasPanel(wx.Panel):
    def __init__(self, parent):
        #Defines Matplotlib display
        #Sets size and position of the Matplotlib display
        wx.Panel.__init__(self, parent, pos=wx.Point(800,0))
        
        #Configures the Matplotlib display
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.FlexGridSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()
        
class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        #Defines 3D display
        wx.Frame.__init__(self, *args, **kwargs)

class App(ShowBase):
    def __init__(self):
        #Configures main window
        ShowBase.__init__(self)
        self.startWx()
        self.frame = Frame(None, wx.ID_ANY, 'Matplotlib Test')
        self.frame.Show()
        self.frame.Layout()
        self.frame.Maximize()
        
        #Configures the 3D display
        wp = core.WindowProperties()
        wp.setOrigin(0,0)
        wp.setParentWindow(self.frame.GetHandle())
    
        base.openMainWindow(type = 'onscreen', props=wp, size=(800, 1000), aspectRatio = 1)
        
        panel = CanvasPanel(self.frame)
        panda = base.loader.loadModel('panda')
        panda.reparentTo(base.render)
        panda.setScale(10, 10, 10)
        panda.setPos(0, 500, -50)
        
App()
3 Likes