Building a Matplotlib GUI with Qt Designer: Part 3

This series of blog posts details the creation of a custom Qt application containing an interactive matplotlib widget and a plot selection list, which controls the currently displayed figure. In Part 1, we constructed our application framework and layout using Qt Designer. Part 2 of this series explored the custom subclass creation that was necessary to add custom logic to our application. In this installment, we will look at adding multiple figures to our application and including their names in the list widget. In addition, we will write some code to change the current figure by selecting from the names in the list widget. The final versions of the Qt Designer UI file and the “custommpl.py” script can be downloaded here.

Adding Items to the List

Adding text to our list is simple. Our list widget, which we called mplfigs, is an instance of the QListWidget class. This class has an addItem method which adds the given string argument to the list. Remember that if we also want to be able to switch figures by selecting names from the list, so to get us started, let’s modify the Main class’s __init__ method and add a new method calledaddfig.

Now any new instances of our application will contain an empty dictionary called fig_dict, which we will use to store our Figure instances by name. The new addfig method takes a name string argument and a Figure instance. The Figure is added to the dictionary under the name key, which is also added to our list widget. To see how this works, change the condition code block at the end of the program as follows. The resulting application window is shown below.

one_nameTo add a new figure, call rmmpl to remove the old figure then use addmpl and addfig to add the next figure. The plot will update and the new names will be added to the list; however, our application will have no way of knowing how to change the plots when you select names from the list.

Changing Plots Using the List

To connect the names in the list to the figure updating code, we need to take advantage of Qt’s signal and slot architecture.  The main Qt documentation has a very nice explanation of this concept, so I’ll just give a very brief overview here. Essentially, any “events” that occurs in a widget trigger a particular “signal”, which is defined by the widget. In our example, when an item in our list widget is selected, it triggers an itemClicked signal from the list, which emits a QListWidgetItem instance. Initially, the signal is not directed anywhere, so nothing happens. However, we can connect this signal to another widget’s slot, which is a (potentially custom) method that handles the emitted information. In our case, when the itemClicked signal is triggered, we want to remove the old figure (rmmpl) and add the figure (addmpl) defined by the emitted QListWidgetItem name. To make this possible, we “connect” the itemClicked signal to a new method that we’ll call changefig. This is more clearly seen in example code.

A few changes have been made to our initialization method. First of all, we connected the itemClicked signal to a new method called changefig. Remember that when this signal is triggered it emits a QListWidgetItem as well, so changefig must accept one argument, which is an instance of the list item. List widget items define a text method, which simple returns the text of the selected item. Once we know the item text, we can remove the old figure and display a new one based on the name defined by the selected text.

Notice that an empty figure instance was added to our plotting window in the initialization method. This is necessary because our first call to changefig will try to remove a previously displayed figure, which will throw an error if one is not displayed. The empty figure serves as a placeholder so the changefig method functions properly.

To test this, let’s add a couple of Figure instances to our application to see what it does. We’ll do this in the conditional code block at the end of the script.

At first, when you run this code, you will be presented with a blank plotting window; however, select one of the plot names from the list widget and see what happens.

success

SUCCESS!!!

Running Our Application from IPython

IPython is an extremely popular and powerful tool for interactive data analysis. In addition, it is well designed to work with external GUI event loops, which makes it possible to run custom applications as well. To get this to work, we must tell IPython that we will be running an external Qt GUI using the %gui qt cell magic (version >2.4 of IPython). With IPython started, we can start our GUI application in the following manner.

This will display our GUI with an empty plot window and figure list. We can recreate our example above by generating each figure and adding them to our application.

In this way, you can interactively process the data then add new figures to the GUI application as needed. This technique also works with IPython’s qtconsole and locally-hosted notebooks.

Emulating IPython Notebooks in WordPress: Part 2

Input and Output

This is my second post about setting my WordPress blog to emulate an IPython notebook interface. In this post, I’ll talk about duplicating the Input/Output box style in the IPython notebook. My first post discussed source code highlighters, child themes, Pandas DataFrames, Matplotlib Figures, and MathJax support.

Output Box

I wanted to have a nice box that wraps all of the output from any of the code presented in the examples. This was fairly easy to accomplish by wrapping output in a division with the class “pyout”, i.e. <div class=”pyout”>…</div>. Then, I updated my CSS file to include the following:

This makes a nice dotted border around all of the code output.

Output Text

Next, to precede all output boxes with the text “Output:” is a little trickier. I could have added this text to every “pyout” division, but that would have been tedious and error prone. Fortunately, jQuery has a wrap function that wraps a given element in another set of tags. In this way, I could wrap all of my “pyout” boxes with another division containing the “Output:” text.

First of all, I wrote a custom JS script that wraps the “pyout” division. In my child theme folder, I created a file called “wrapper.js” that included the following code:

All “pyout” boxes are now surrounded by another division classed as “pyoutwrap”. Modifying my theme’s CSS file as below makes the “Output:” text bold and slightly larger than the actual code output.

Making these changes has no immediate effect, though, because you need to register this JS script with WordPress for it to be activated. This is accomplished by adding a couple of lines to “functions.php”, which is shown below in its entirety.

Much of this code was covered in the section on child themes from my previous post; however, notice that a new function wp_enqueue_script incorporates my new JS file into my site. A couple of the arguments to this function are very important, so they will all be described here. The first argument is simply the name with which I would like to register this script with WordPress. The second argument is the file location, making sure this is the full path by prefixing get_stylesheet_directory_uri(). The array argument ensures that jQuery is loaded before this script, otherwise things won’t work correctly. The string is just a version number, which is unnecessary, so I just put in a placeholder of ‘1.0’. The final argument, true, is critical. It puts this script at the end of the HTML, just before the closing </body> tag. In this way, the function is executed after the entire page is loaded. Otherwise, the script is loaded into the HTML head and is executed before the body, including my “pyout” box, is loaded.

Input Text

I followed a very similar procedure to add “Input:” before all of my code samples. Again, I used jQuery’s wrap function on all “crayon-syntax” classes. Below is the additional function call in “wrapper.js” and some new styling in “style.css”, respectively. I also changed Crayon’s “Top Margin” to “0px”, which can be done through Crayon’s Settings page.

Although this method works just fine, it wraps every Crayon code instance with the “pyinwrap”. That means that even non-Python code blocks will be prefaced with “Input:”. For now, this is going to be the best solution until I can figure out how to add Python-specific wrappers.

In Action

Now that everything is set, all of my Python input and output has a similar appearance to an IPython notebook session. (Not perfect, but close enough.)

Hello World!

Emulating IPython Notebooks in WordPress

I purchased this website many years ago with the intention of starting my own blog. At the time, I was teaching myself Python, and I thought it wouldn’t be that hard to write my own custom website using CGI and MySQL. Please don’t ever do this! Although I learned quite a bit about web servers, HTML, CSS, and SQL databases, it was way too much work, and my blog never took off.

Fast forward to 2015. After receiving yet another auto-payment notification for my unused website, I decide the time has finally come to make use of it. Fortunately, my hosting provider has an auto-install option for a WordPress blog. WordPress is popular. It’s apparently easy to use… Let’s give this a try.

One thing I’d like to write about is Python programming for data analysis with included examples. I’m a heavy user of IPython notebooks for data analysis, so I’d like to be able to incorporate some of the notebook display features into my blog. Unfortunately, a web search for some ideas on uploading notebooks to WordPress was surprisingly unhelpful given WordPress’s popularity.

IPython provides a tool, nbconvert, which can convert notebook files directly to HTML. This is great because you can easily send a webpage of an analysis to a colleague, for example. It is also the basis of the NBViewer website. This might make a good starting point; however, one of my biggest problems with the IPython notebook is that markdown cells are not spell-checked. My spelling skills are atrocious, so my notebooks are always rife with errors. Knowing this, I was reluctant to upload notebooks directly and decided to pursue other options.

Ultimately, I found a bunch of plugins and hacks that gave me much of the display functionality for emulating the look and feel of the IPython notebook. My adventures are documented below in case others might find this useful.

Code Highlighting

This was the easiest part of the whole process. There are many syntax highlighters available as WordPress plugins. I took a quick look at a couple of “Top ### Code Highlighting” pages for inspiration, but it seemed like all the highlight plugins are fairly similar. I finally chose Crayon, not for any particular reason, except that it was pretty high up on many of the top lists. The default display properties were not optimal for my taste, so I modified several options through the “Settings” link under Crayon on the Plugins admin page. The changes are as follows: 1) Display the Toolbar to “Never”, 2) Enable plain code view and display to “Disable Mouse Events”, 3) and Language Fallback to “Python”.

Now, my “Add Post” editor contains a Crayon button, which opens a source code import window, from which I can also alter any of the numerous global display options. To add some code from a notebook, simply copy-and-paste it into the Crayon source code window. Once inserted, the source code is wrapped in the appropriate pre tags. For example, the following highlighted Python code

Appears as this in the Text editor window after insertion with Crayon:

<pre class="lang:python decode:true " >print('hello')</pre>

Creating a Child Theme

After some experimentation, I realized that I was going to need to modify my site theme with some custom CSS, at the minimum. I read up on this topic on the web, and most people recommend that you create a Child Theme when doing any customization. A child theme is essentially an overlay on top of another base (Parent) theme. There are a couple of advantages here. First, if the underlying theme is updated, you won’t lose your customizations. In addition, the child overlay is a fairly minimal set of files, so you could transfer your changes to a new theme with very little effort. The WordPress documentation on Child Themes is a pretty decent place to find step-by-step information.

As of this writing, this site is using the default “twentyfifteen” theme. In my themes folder, wp-content/themes, I created a new theme folder called twentyfifteen-child that contains two files: style.css and functions.php.

The functions.php file simply contains a function theme_enqueue_styles that loads the main style sheet from the underlying parent theme. My file is shown below:

The style.css file is simply your custom style sheet that must contain a comment header with a tag Template that names the underlying parent theme. I simply copied the parent theme style.css file and added the “Template” line. My file is shown below:

Then I simply changed to the “twentyfifteen-child” theme from the WordPress theme manager.

Pandas DataFrame Tables

Pandas is a powerful data analysis library for Python. Among other things, Pandas provides a tabular data structure called DataFrame, which is very similar to the equivalently named structure in R. In IPython’s notebook and Qt Console interface, Pandas DataFrames are printed as nice HTML tables. For example, below is a chunk of code and the IPython output.

one two 0 b
0 5 1 A D
1 8 9 B A
2 9 3 C E

Emulating this was a little tricky. As a first step, convert your notebook to HTML:

$ ipython nbconvert test_notebook.ipynb

Open the resulting HTML file in a text editor. There is a ton of boilerplate junk here, but you can easily find the table by searching for “<table”. Copy all of the text up to and including the closing </table> tag, and paste this into the Text Post editor. This won’t work in the Visual editor, which does some conversions behind the scenes. Make sure the table class is set to “dataframe”. Wrap the table in a div with the class name “dftable”. Here is the raw HTML for the above table:

Next, I modified the CSS file of my Child Theme (style.css) to alter the default appearance of this class of table and the surrounding div.

Perhaps not the most elegant solution, but it does the trick.

Matplotlib Figures

IPython can display Matplotlib figures inline with the rest of the code and output. On export to HTML, the image is embedded into the raw HTML in base64 encoded text. Again, this is great when sharing the HTML files with collaborators, because everything is contained in one file. However, WordPress doesn’t handle this elegantly. In this case, using Matplotlib’s savefig command will create a hard copy version of the figure in addition to inlining it in the notebook. For example, the following set of commands will produce a very simple plot in a notebook along with a PNG of the same figure called “testing.png”:

testing

To emulate an IPython notebook with the inline set, I’ll probably just drop the savefig calls when transferring the code into my post. Then I can simply use the “Add Media” button in my post editor to upload and include the figure. An advantage of this procedure is that the figures are given their own URL, which people can reference in the future.

MathJax

Again, there are a bunch of MathJax plugins available for WordPress. I chose “Simple MathJax” because it sounded… simple. And it seemed to best emulate the way MathJax behaves in IPython notebook markdown cells. Once installed and enabled, I can can add inline MathJax by using a single \$ sign. For example, \$\frac{1}{2}\$ will be rendered as $\frac{1}{2}$. Block equations can be included with the double dollar sign \$\$, such that \$\$\alpha^{2}\$\$ is rendered as $$\alpha^{2}$$

EDIT: This following paragraph is no longer necessary. I filed a PR with these changes to this plugin. It has been merged into master. I’ll leave this here for reference, though.

One issue is that the escaping the dollar sign is not supported by default. In order to set this, go to the Plugins page and select “Edit” under Simple MathJax. This opens a text editor for modifying this plugin. Search for the following line:

Add processEscapes: true to the end of this line as such:

Now your should be able to add dollar signs to your post by preceding them with \, such as \$.

Final Thoughts

That covers most things that I want to do for the time being. However, I’ll probably come back to this topic again once I get frustrated with some other odd behavior of my site. I hope others find this useful. Leave me a comment if you want me to add/clarify anything.

Follow-up

I wrote a second post that shows how to add “Input:”/”Output:” text before all code boxes.