Skip to main content

Data Plotting in wxPython

wx.lib.plot

wxPython has its own plotting library, which provides simple way of drawing large number of data on a canvas. It is convenient to use and it is fast. However you have only one axis per canvas and you can plot 2D graphs only.


To plot a line graph like above, you create line objects using numpy
Source file
  214                 x = np.linspace(0,10,500)
  215                 y = np.sin(x)
  216 
  217                 # create lines
  218                 line1 = wxplot.PolyLine(list(zip(x, np.sin(x))),
  219                         colour='red', width=3, style=wx.PENSTYLE_DOT_DASH)
  220                 line2 = wxplot.PolyLine(list(zip(x, -np.sin(x))),
  221                         colour='blue', width=3, style=wx.PENSTYLE_LONG_DASH)
Then generate a graphics object and render it on the canvas Source file
  223                 # create a graphics
  224                 graphics = wxplot.PlotGraphics([line1, line2])
  225                 self.pnlPlot.Draw(graphics)
Here the canvas is implemented on the panel, self.pnlPlot. So you can embed the panel into any wx.Window object.

Matplotlib WXAgg

For more professional plot, you can use matplotlib more specifically matplotlib WXAgg backend, where almost all the matplotlib features are available to wx.Python.  Thus you can plot contour


or more sophisticated plots as shown below very easily.


In this case, the WXAgg figure object and the canvas object are implemented on a wx.Panel: Source file
   34 class MplGraph(wx.Panel):
   35 
   36     def __init__(self, parent, hideToolbar=False):
   37 
   38         wx.Panel.__init__(self, parent)
   39 
   40         # mpl figure object
   41         self.figure = Figure()
   42         # mpl canvas object
   43         self.canvas = FigureCanvas(self, -1, self.figure)
and exposed: Source file
   65     ## return canvas object
   66     def GetCanvas(self):
   67         return self.canvas
   68 
   69     ## return figure object
   70     def GetFigure(self):
   71         return self.figure
Thus, you can use them just as you use matplotlib. For the above example, the shade plot on the left was generated by: Source file
  191             elif evt.GetId() == self.idShade:
  192                 # clear previous plot
  193                 self.pnlPlot.Clear()
  194                 # acquire new axes
  195                 ax1 = self.pnlPlot.AddSubPlot(121)
  196                 # we need figure object too
  197                 fig = self.pnlPlot.GetFigure()
  198 
  199                 # colormap
  200                 cmap = matplotlib.cm.copper
  201 
  202                 # import LightSource
  203                 from matplotlib.colors import LightSource
  204 
  205                 y,x = np.mgrid[-4:2:200j, -4:2:200j]
  206                 z = 10 * np.cos(x**2 + y**2)
  207                 ls = LightSource(315, 45)
  208 
  209                 rgb = ls.shade(z, cmap)
  210 
  211                 ax1.imshow(rgb, interpolation='bilinear')
  212                 im = ax1.imshow(z, cmap=cmap)
  213                 #im.remove()
  214                 #fig.colorbar(im)
  215                 ax1.set_title('shaded plot')
and the right 3D surface plot is generated by: Source file
  217                 # import Axes3D
  218                 from mpl_toolkits.mplot3d import Axes3D
  219                 ax2 = self.pnlPlot.AddSubPlot(122, projection='3d')
  220 
  221                 X = np.arange(-5,5,0.25)
  222                 Y = np.arange(-5,5,0.25)
  223                 X,Y = np.meshgrid(X,Y)
  224                 R = np.sqrt(X**2 + Y**2)
  225                 Z = np.sin(R)
  226                 
  227                 #surface plot
  228                 surf = ax2.plot_surface(X,Y,Z, cmap = matplotlib.cm.coolwarm,
  229                         linewidth=0, antialiased=False)
  230                 
  231                 ax2.set_title('3d surface plot')
source code

Comments

Popular posts from this blog

A Simple STM32 Example Project

Most of the embedded projects share certain initial steps. You need to confirm the clock settings before doing anything, then you want to have debug connection via a UART channel since it is cheap  but still it can provide useful information for debugging. Let us start with CubeMX. You select a device/board of your choice, set up the pinouts for one GPIO output and one UART port. Configure the clock if necessary then create a project. Clock Checking using SysTick The sanity of the clock setting can be done by checking the SysTick interval. All Cortex-M series core have SysTick timer by default, which should fire at 1msec interval while the MCU is active. In the STM32Cube, the SysTick is initialized by HAL_Init() call, which in turn calls SysTick_Config() in CMSIS. Once the SysTick is initialized, it generates 1 msec interrupt and this interrupt is handled by SysTick_Handler() according to the Cube framework. Source file 1 /** 2 * @brief This function handles

STM32 USB MSC Device with FLASH memory

USB Mass Storage Class framework implements bulk-only-transfer (BOT) with SCSI protocol. USB packets from the host eventually converted SCSI transport commands by the middleware, in which data is exchanged (read / write) in the unit of logical block, typically 512 bytes. This SCSI commands works well with SD card system where a dedicated controller does the job of managing the actual memory elements. If you want to use a FLASH chip as a memory unit instead, you need to handle read / write operation directly. Fortunately, most of flash memory support 4KB block erase. This makes the 4096 bytes as a natural choice for the size of the logical block in the file usbd_storage_if.c. In this case, 8Mbit Flash memory was used. During initial enumeration, this information is registered to the host. The middleware maintains one logical block size of buffer and handles USB transaction where each payload is only 64 bytes. It then calls SCSI requests to store / retrieve data to / from physical

STM32 USB MSD with SD Card

Build a low level driver for SD card, then the glue logic for FatFs and USB MSD is pretty much the same as Flash memory case posed before. In case of SD card, sector size is 512 in most of the cases. Thus the memory requirement is much relaxed. You can even allocate a file buffer that is bigger than the sector size. FatFs site has a  dedicated page for MMC/SDC, on which you can find fairly detailed explanation about how to interface MMC/SDC via SPI bus. Implementation should be straightforward until you encounter with cheap SD cards that do not behave very well. In such cases, you either have to protect your code with redundancy or just stick with quality devices. If you choose SanDisk or Kingston brand, you will be safe. ADATA on the other hand, frequently generates timeout error at first try. Most of the SD card sockets have a pin to detect the presence of the card. This pin is usually connected to GND pin or some other pin. You can use this to generate interrupt whenever a ca