0

I am trying to plot 1D txt files in a part of the window created using wxpython. For this purpose, a directory selection tool was included which lists all txt files. Now, I would like to select a txt file and plot it in a panel on the right side.

Further, I am thinking to implement a button that does some operations on the data and replot again.

What I have tried is this :

import os
import wx
import numpy as np
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
 
 
class mainFrame (wx.Frame):
    def __init__(self):
        super().__init__(None, id=wx.ID_ANY, title=u" test  ",
                         size=wx.Size(854, 698),
                         style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
 
        self.SetSizeHints(wx.Size(600, -1), wx.DefaultSize)
 
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.panel = MainPanel(self, style=wx.TAB_TRAVERSAL)
        self.Layout()
 
        sizer.Add(self.panel, 1, wx.EXPAND, 0)
        self.SetSizer(sizer)
        self.Layout()
        self.Centre()
 
        # Connect Events
        self.panel.dirPicker.Bind(wx.EVT_DIRPICKER_CHANGED, self.dirPickerOnDirChanged)
        self.panel.listBox.Bind(wx.EVT_LISTBOX, self.listBoxOnListBox)
 
        # ------------ Add widget program settings
 
        # ------------ Call Populates
 
        self.Show()
 
    # Virtual event handlers, override them in your derived class
    def dirPickerOnDirChanged(self, event):
        self.FilePath = event.GetPath()
        self.populateFileList()
 
    def populateFileList(self):
        self.panel.listBox.Clear()
        allFiles = os.listdir(self.FilePath)
 
        for file in allFiles:
            if file.endswith('.txt'):
                self.panel.listBox.Append(file)
 
    def listBoxOnListBox(self, event):
        try:
            selected_file = event.GetString()
            file_address = os.path.join(self.FilePath, selected_file)
 
            # load file
            data = np.loadtxt(file_address)
 
            # select the first column
            if isinstance(data, np.ndarray):
                print("\tdata is np.array")
                dim = data.ndim
                if dim == 2:
                    input1D = data[:, 0]
                else:
                    input1D = data
 
                print(input1D.shape)
                # plot here
            else:
                print("\tdata is not np.array")
        except:  # Do not use bare except
            print("Some error.")
 
 
class MainPanel(wx.Panel):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.FONT_11 = wx.Font(11, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL,
                               wx.FONTWEIGHT_NORMAL, False, "Consolas")
        self.FONT_12 = wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                               wx.FONTWEIGHT_NORMAL, False, wx.EmptyString)
        self.FONT_13 = wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                               wx.FONTWEIGHT_NORMAL, False, wx.EmptyString)
        self.FONT_14 = wx.Font(14, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL,
                               wx.FONTWEIGHT_BOLD, False, "Consolas")
        self.FONT_16 = wx.Font(16, wx.FONTFAMILY_SCRIPT, wx.FONTSTYLE_NORMAL,
                               wx.FONTWEIGHT_BOLD, False, wx.EmptyString)
 
        sizer = wx.BoxSizer(wx.VERTICAL)
 
        quick_display = self._quick_display()
        directory_sizer = self._directory_sizer()
        list_box_sizer = self._list_box_sizer()
        self.text_details = self._detail_input()
        details_sizer = self._details_sizer()
        status_sizer = self._status_sizer()
 
        message_sizer = wx.BoxSizer(wx.VERTICAL)
        message_sizer.Add(details_sizer, 1, wx.EXPAND, 5)
        message_sizer.Add(status_sizer, 1, wx.EXPAND, 5)
 
        sizer.Add(quick_display, 0, wx.EXPAND, 0)
        sizer.Add(directory_sizer, 0, wx.EXPAND, 0)
        sizer.Add(list_box_sizer, 1, wx.EXPAND, 0)
        sizer.Add(message_sizer, 1, wx.EXPAND, 5)
 
        self.SetSizer(sizer)
 
    def _quick_display(self):
        quick_display = wx.StaticText(self, label=u"quick display")
        quick_display.Wrap(-1)
        quick_display.SetFont(self.FONT_16)
        return quick_display
 
    def _directory_sizer(self):
        sbSizerDir = wx.StaticBoxSizer(wx.StaticBox(self, label=u" working directory"))
        self.dirPicker = wx.DirPickerCtrl(sbSizerDir.GetStaticBox(), message=u"Select a folder")
        sbSizerDir.Add(self.dirPicker, 0, wx.ALL | wx.EXPAND, 5)
        return sbSizerDir
 
    def _list_box(self):
        listBoxChoices = []
        self.listBox = wx.ListBox(self, size=wx.Size(300, -1), choices=listBoxChoices)
        self.listBox.SetMinSize(wx.Size(250, -1))
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.listBox, 1, wx.ALL, 10)
        return sizer
 
    def _plot_sizer(self):
        self.panelPlot = PlotPanel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.panelPlot, 1, wx.EXPAND | wx.ALL, 5)
        return sizer
 
    def _list_box_sizer(self):
        file_list_sizer = self._list_box()
        bSizer_plot = self._plot_sizer()
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(file_list_sizer, 1, wx.EXPAND, 0)
        sizer.Add(bSizer_plot, 1, wx.EXPAND, 5)
        bSizerSplitHor = wx.BoxSizer(wx.HORIZONTAL)
        bSizerSplitHor.Add(sizer, 1, wx.EXPAND, 2)
        bSizerSplit = wx.BoxSizer(wx.VERTICAL)
        bSizerSplit.Add(bSizerSplitHor, 1, wx.EXPAND, 0)
        return bSizerSplit
 
    def _detail_label(self):
        detail_label = wx.StaticText(self, label="Details")
        detail_label.Wrap(-1)
        detail_label.SetFont(self.FONT_14)
        return detail_label
 
    def _detail_input(self):
        text_details = wx.TextCtrl(self, size=wx.Size(250, -1))
        text_details.SetFont(self.FONT_11)
        return text_details
 
    def _button_sizer(self):
        self.button = wx.Button(self, label=u"do some operation")
        self.button.SetFont(self.FONT_13)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.button, 0, wx.ALL, 5)
        return sizer
 
    def _details_sizer(self):
        detail_label = self._detail_label()
        button_sizer = self._button_sizer()
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(detail_label, 0, wx.ALL, 5)
        sizer.Add(self.text_details, 1, wx.EXPAND, 5)
        sizer.Add(button_sizer, 1, wx.EXPAND, 5)
        return sizer
 
    def _status_sizer(self):
        self.staticline3 = wx.StaticLine(self)
        self.status_label = wx.StaticText(self, label=u"Status bar")
        self.status_label.Wrap(-1)
        self.status_label.SetFont(self.FONT_12)
        self.staticline4 = wx.StaticLine(self)
        self.textCtrl_status = wx.TextCtrl(self)
        self.textCtrl_status.SetFont(self.FONT_11)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.staticline3, 0, wx.EXPAND | wx.ALL, 5)
        sizer.Add(self.status_label, 0, wx.ALL, 5)
        sizer.Add(self.staticline4, 0, wx.EXPAND | wx.ALL, 5)
        sizer.Add(self.textCtrl_status, 0, wx.ALL | wx.EXPAND, 5)
        status_sizer = wx.BoxSizer(wx.VERTICAL)
        status_sizer.Add(sizer, 1, wx.EXPAND, 5)
        return status_sizer
 
 
class PlotPanel(wx.Panel):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.SetMinSize(wx.Size(100, -1))
 
 
if __name__ == "__main__":
    app = wx.App(False)
    frame = mainFrame()
    app.MainLoop()
 

This creates a window as follows :

wx test window

The right portion is assigned as a panel, and I not sure how to place the matplotlib plot in it. Thank you.


There are several good questions on SE probing this topic, such as Q1 and Q2; however, most are limited to the plot being shown on the main window.

2
  • 1
    IMHO your code is confused and certainly does not conform to PEP8. This is not mandatory, but it is a standard the most python developers will find easier to read and possibly more willing to reply. (I've not corrected all your camelCase). I have refactored your code here. I have adapted most of the spaghetti and placed the panel in a class on its own rather than have everything in one class. It might be easier to see what is going on. Commented Apr 3, 2022 at 13:49
  • Possibly you have too much detail; consider providing a minimal reproducible example Commented Apr 3, 2022 at 13:53

1 Answer 1

0

wxGlade includes some wxPython / matplotlib examples. Use these as starting point. https://github.com/wxGlade/wxGlade/tree/master/examples

Sign up to request clarification or add additional context in comments.

3 Comments

This is not an answer - it is a comment
Well, feel free to do other peoples homework. Actually, it's easiest to start with working code.
Just trying to help ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.