Logbook + Scratchpad


Two Python packages I've come across while experimenting with MIDI programming:

  • pyknon for music theory and easy MIDI file generation
  • pychord for chord parsing and generation

I was not looking for any libraries explicitly, as I was having fun creating some of their features from scratch. As usual, serendipity helped: I've found both in another project that I cannot recall at this very moment.

#Python #music

A while ago I published a Python client for Alda, a project I've liked since I learned about it. Recently, though, I've had a desire to go “back to the basics” and deal with MIDI directly.

After a long time, I've picked Mido up again to write some MIDI files programmatically. I've even managed to make it run both on Windows and on MacOS, which required a little more setup. It was a good chance to review some aspects of the MIDI protocol itself, which I'm using for some experiments.

#Python #music #MIDI

In some previous posts I have mentioned in passing an old project of mine about fractals with Python. Although it still needs updates and more explanation, I have decided to bite the bullet and publish it as-is, with the aim of improving it over time rather than having it collecting virtual dust on my hard disk.

The project is called chaopyc (a portmanteau of “chaotic” and “Py(thon)”) and is available on GitHub.

#Python #fractals #chaos

After taking a look at both PyQtGraph and VisPy, I started to think about alternative 3D libraries mainly for two reasons:

  • I use Jupyter Notebooks way more than standalone apps for data visualization, so I'd prefer a library that integrates well with notebooks.
  • I would prefer well-maintained libraries, and VisPy's main maintainer has issued a call for help to continue supporting the project. Furthermore, there are not many references to any of the two libraries when looking for Python 3D libraries.

A few alternatives I have found:

#Python #3D

I've decided to try VisPy by adapting my previous PyQtGraph example. In the process I have figured out something I got wrong about the update function: I thought the loop that updates the points for the scatterplot had to be inside the update, and this works with PyQtGraph but doesn't with VisPy. (A GitHub Issue gave me the idea.) This brought me to reconsider the role of update as a function that should include the changes to data as a timer-controlled operation too. In other words, there should not be a loop inside update; rather, the loop (or the condition) variable has to be updated inside but declared outside.

Beside this important realization (which I would have probably come across had I read more about Qt and timers), for this use case I haven't seen any big differences between VisPy and PyQtGraph except that VisPy has an easier API to work with, for example:

  • The main application in VisPy can just be imported from the main module with from vispy import app.
  • Views are added to a SceneCanvas in VisPy.
  • There are no specific “GL widgets” in VisPy, so a PyQtGraph GLScatterPlotItem is just a Markers “visual element”.
  • There are no “Qt modules” in VisPy, so a QTimer from pyqtgraph.Qt.QtCore in PyQtGraph is just an app.Timer.

#Python #OpenGL

One of the experiments I did as part of the old project I have recently written about was about animating a 3D plot using OpenGL from PyQtGraph. The code was inspired pretty much to one of the PyQtGraph examples from its GitHub repository, where – for future memory – the main components are the following:

  • A Qt QApplication as the container Qt app.
  • A GLViewWidget as the main OpenGL view component.
  • A GLGridItem to visualize a grid (not essential).
  • A GLScatterPlotItem as the actual scatterplot graph.
  • A QTimer to repeatedly call an update function, which includes two actions:
    • setData to plot the data points
    • orbit to make the camera spin around the view center (neat!)

I've recently revisited the example to put everything in a class rather than relying on globals. I'll publish it at some point.

#Python #OpenGL

While looking again at some code I wrote quite some time ago to animate a graph with OpenGL in PyQtGraph, I learned that some OpenGL libraries (including PyQtGraph) still use the Fixed Function Pipeline. Apparently, VisPy is a good replacement as it is based on the more modern shaders instead.

I haven't looked at any other Python OpenGL packages yet, but I might give VisPy a try.

#TIL #OpenGL #Python

An aspect I liked about the wxPython toolkit I recently rediscovered is the separation of GUI design from GUI functionality implementation. This is achieved through the usage of XRC files, which are XML files describing the appearance of a GUI. XRC files can be created through XRC editors such as wxGlade, then imported in Python code with functions from the wx and wx.src modules.

I haven't been writing or using GUIs in Python for a while since I started using Jupyter Notebook, but I consider this kind of toolkits very useful for standalone applications not based on a browser (which, admittedly, may be less and less nowadays).

#python #GUI

I have loved fractals since I first learned about them as a kid, thanks to my mother. At first I loved the colors and the variety of shapes, then the generative aspect (a simple formula can generate such a complex pattern!), and finally the math behind (complex numbers, non-linearity, fractal dimension, and so on).

The software I was using as a kid was called Winfract, the Windows version of Fractint, which was and is itself very flexible and feature-rich. I am very grateful to Fractint developers for having created such a great software, as when I first learned Python and NumPy more than 10 years ago, I attempted to replicate some of its features. This resulted in a lot of research on NumPy, GUIs, and graphics (including Matplotlib and OpenGL), some of which I mentioned in the previous post.

I am resurrecting and refurbishing this very old code, which I will make available soon. It is by no means a complete product, for which there are much more advanced solutions such as XaoS; it's more a collection of experiments. Yet, I am happy that, back then, I managed to replicate many of the formulae that Fractint provided, and also that I ventured into 3D data visualization and GUI design.

#python #fractals #graphics

The reason why I've mentioned legacy code in the last post is that I've recently reopened an old project of mine (which I'll expand upon in another post), and I've immediately seen a number of Python packages that either are outdated, have undergone a number of changes, or simply I have forgotten about.

  • pylab, a Matplotlib plotting interface, has been replaced by pyplot.
  • mplot3d, used in Matplotlib to create 3D plots, now does not require to be imported explicitly.
  • PyQt, the Python bindings to the Qt framework, is now at version 6. Obviously this changes some of the API.
  • VPython, an easy-to-use 3D library that I've used quite a lot in the past, now defaults to using a Jupyter notebook rather than a standalone viewer.
  • I had largely forgotten about Mayavi, an interactive 3D data visualization library. I'll need to take a look at it again. A small practical note: pip install mayavi does not work with version 4.8.1; instead, use pip install https://github.com/enthought/mayavi/zipball/master.
  • wxPython, my favourite Python GUI toolkit, and pyqtgraph, a more specialized graphics and GUI library, still seem largely the same. I have just not used them in a while.

#python #legacy