Resolved: Matplotlib figures not showing up or displaying

matplotlib_osx_vs_ubuntu

I think a better title for this blog post might be: How I lost a day of productivity to Ubuntu, virtual environments, matplotlib, and rendering backends.

Over the weekend I was playing around with deep learning on my Ubuntu system and went to plot the accuracy scores of my classifier. I coded up a quick Python script using matplotlib, executed the script, only to not have the figure displayed to my screen.

My script executed just fine. No error messages. No warnings. But there was still no plot to be found!

This is actually a common problem I’ve ran into over the past few months, especially when working with Debian based operating systems such as Ubuntu and Raspbian. This issue is only further compounded when utilizing virtual environments via the virtualenv and virtualenvwrapper packages.

The issue actually stems from the matplotlib backend not being properly set, or from a missing dependency when compiling and installing matplotlib. Luckily, after a lot of trial and error (and spending an entire day trying to come up with a solution), I have been able to resolve the problem and get matplotlib figures to show up and display on my screen on both the Ubuntu and Raspbian operating systems (and when using Python virtual environments).

While this post is not exactly related to computer vision or OpenCV, I still want to share my experience and solution with other PyImageSearch readers. Matplotlib is a heavily used package in the Python scientific community and I hope that this article helps other readers resolve this strange and hard to pinpoint issue.

Setting the stage

Let’s go ahead and set the stage.

  • We’re using a Debian based operating system such as Ubuntu or Raspbian.
  • We’re (optionally) utilizing Python virtual environments via virtualenv and virtualenvwrapper.
  • And our goal is to take the following image (left) and compute a grayscale pixel intensity histogram for it using matplotlib (right):
Figure 1: Our end goal is to utilize matplotlib to display a grayscale pixel intensity for the image on the left.

Figure 1: Our end goal is to utilize matplotlib to display a grayscale pixel intensity for the image on the left.

Since we are using matplotlib, let’s create a new virtual environment called plotting :

Now that we’re in the plotting  environment, let’s install numpy , scipy , and matplotlib :

Awesome — all of our Python dependencies are installed. Now, let’s write a few lines of code to load the image, convert it to grayscale, compute a histogram over the grayscale image, and finally display it to our screen. I’ll throw all this code into a file named grayscale_histogram.py :

The code here is fairly straightforward. Lines 1 and 2 import matplotlib  and cv2 . We then load our image and convert it to grayscale (Lines 4-9). From there the cv2.calcHist  function is used to compute a histogram over the grayscale pixel intensities. Finally, Lines 14-22 plot the histogram using matplotlib .

To execute our script, all we need to do is fire up and shell and issue the following command:

When I execute the code on my OSX machine in the plotting  virtual environment, the histogram is computed and both the grayscale image and histogram are displayed to my screen:

Figure 2: Using OSX, I can successfully plot and display my grayscale histogram using matplotlib.

Figure 2: Using OSX, I can successfully plot and display my grayscale histogram using matplotlib.

However, when I go over to my Ubuntu 14.04 machine and execute the exact same code all I see are my images:

Figure 3: I have executed the *exact same* code on my Ubuntu system in the plotting virtual environment. All I see are my images -- where did my histogram go? Why is there no error message?

Figure 3: I have executed the exact same code on my Ubuntu system in the plotting virtual environment. All I see are my images — where did my histogram go? Why is there no error message?

Which leads to the question: Where is the histogram?”

As we can see from the terminal output, the script executed just fine. No errors were displayed. No warning messages printed to my console. But yet there is not plot!

Resolved: Matplotlib figures not showing up or displaying

As I hinted at earlier in this post, the missing figure issue is related to the matplotlib backend that does all the heavy lifting behind the scenes to prepare the figure.

Popping into a shell, I can access the matplotlib backend using the matplotlib.get_backend() :

On my Ubuntu machine this gives me a value of agg ; however, through my testing and debugging, this value needs to be TkAgg  for the TkInter windowing system (at least when using Ubuntu and Raspbian).

Luckily, we can resolve this issue by using apt-get  to install a few libraries:

But we’re not quite done yet. In order to get matplotlib to recognize the TkInter GUI library, we need to:

  • Step 1: Access our plotting  virtual environment via workon plotting .
  • Step 2: Use pip to uninstall matplotlib (since we installed it via pip earlier in this article).
  • Step 3: Pull down matplotlib from the GitHub repo.
  • Step 4: Install matplotlib  from source using setup.py .

I can accomplish these steps using the following commands:

Again, you’ll want to ensure that you have installed TkInter via apt-get  before performing these steps.

After matplotlib  has been installed via source, let’s execute the get_backend()  function again:

Sure enough, we now see the TkAgg  is being used as the matplotlib  backend.

Note: You can explicitly instruct matplotlib  to use the TkAgg  backend by making a call to matplotlib.use("TkAgg") ; however, this won’t do you much good if the TkInter dependencies are not installed.

And now when we execute our grayscale_histogram.py  script, just like above:

We should now see both our grayscale image along with our histogram:

Figure 4: Success! Our matplotlib figure is now showing up! All we need to do was change the matplotlib backend.

Figure 4: Success! Our matplotlib figure is now showing up! All we need to do was change the matplotlib backend.

We have now fixed our issue — matplotlib figures are successfully being displayed on our screen!

Granted, this solution is a bit of a pain in the ass, but it’s fairly straightforward and gets the job done. If you have any other suggestions or comments, please feel free to leave them in the comments section.

What about the Raspberry Pi?

The Raspbian operating system, which many Raspberry Pi’s run, is Debian based just like Ubuntu. If you are having the same problems with matplotlib figures not displaying on your Raspberry Pi, the fix detailed in this blog post will resolve your plotting woes.

Can’t you just install matplotlib via apt-get?

The astute Debian user may be wondering why I didn’t simply install matplotlib  via apt-get , like this:

The reason is because I’m a heavy user of Python virtual environments and strictly believe in keeping my Python environments sequestered and independent of each other. If you use apt-get  to install matplotlib  you lose control over what version of matplotlib  you want to install — you simply have to use with whatever version is in the apt-get  repository. This also muddles your system install of Python which I try to keep as clean as possible.

All that said, every time I have installed matplotlib  via apt-get  all of my dependencies were correctly installed and I was able to display my figures without a problem, so if you do not care about Python virtual environments, then the apt-get  solution is a good way to go. But again, I really recommend using virtual environments.

Summary

In this blog post I detailed how to resolve a pesky issue where matplotlib  figures are not displayed to your screen. Symptoms of this problem include clean script execution (i.e. no error messages and no warnings) printed to your terminal, and yet your plot is not displayed. I have regularly encountered this problem when using Debian based operating systems such as Ubuntu and Raspbian. The problem is only further compounded when using Python virtual environments.

Resolving this matplotlib  issue involves manually installing dependencies via apt-get  and adjusting the matplotlib backend to use TkAgg , followed by compiling and installing matplotlib  from source. Afterwards, the issue seems to be resolved.

While this post wasn’t related to computer vision, the matplotlib  library is heavily used in the scientific Python community, so not having your matplotlib  figures displayed can be extremely frustrating and annoying. I hope this post helps other readers who encounter a similar problem.

I’ll be back next week with more computer vision posts!

, , , , , ,

27 Responses to Resolved: Matplotlib figures not showing up or displaying

  1. Thomas Caswell September 7, 2015 at 12:30 pm #

    You can control which backend is used via the matplotlibrc file and you should not need to install from source to get the TkAgg backend to work in a venv.

    Interestingly, this is the inverse of the perennial SO question of ‘how do I make plots without opening a gui window’

    • Adrian Rosebrock September 8, 2015 at 7:30 am #

      You can control the backend via the .matplotlib file and the matplotlib.use() function. However, that will not help if the backend is not actually installed. The most important step is to grab the dependencies via apt-get, at which point you could just set the backend manually, but a re-compile from source will automatically pick them up, which I find preferable.

  2. Hilman January 29, 2016 at 6:26 am #

    Hey Adrian. A little question.
    I am on Mac El Capitan, when I entered

    “$ sudo apt-get install tcl-dev tk-dev python-tk python3-tk”

    into the command line, I got “sudo: apt-get: command not found” message. What should I do?

    • Adrian Rosebrock January 29, 2016 at 7:34 am #

      This blog post is for Ubuntu, not OSX — hence the apt-get command is not part of OSX. Are you having trouble displaying matplotlib plots on OSX?

      • Hilman January 30, 2016 at 12:28 am #

        Yes. I believe it is because of the virtual environment has some conflicts with the matplotlib.

        • Adrian Rosebrock January 30, 2016 at 12:01 pm #

          Indeed, there are some issues with the latest version of matplotlib and Python virtual environments. There are a few workarounds, but by far the easiest is to use an earlier version of matplotlib:

          The key step here is to to checkout the 1.4.3 version before installing.

          • Hilman January 31, 2016 at 5:45 am #

            Hey Adrian, I’ve done as above (except I am in cv environment). I got this output:

            ‘* The following required packages can not be built:
            * freetype’

            What should I do?

            Thanks in advance.

          • Adrian Rosebrock January 31, 2016 at 8:58 am #

            Can you share your full output using GitHub Gists or PasteBin? It’s hard to diagnose what the error message is without seeing the full trace.

          • Hilman February 1, 2016 at 7:19 am #

            Like this? :

            https://gist.github.com/hilman-dayo/39648eb29704ab560c47

          • Adrian Rosebrock February 2, 2016 at 10:38 am #

            Yes, that helps with the formatting a lot. I did a quick search and it seems like this might be an open issue with matplotlib. I would suggest posting your error message + steps taken to reach the error message in this GitHub Issue.

  3. Mootaz February 20, 2016 at 4:16 pm #

    Hi Adrian, I would thank you, I also spent long hours searching in forums why images were not displayed on my Raspberry, then discovered the problem but didn’t find solution, unto I returned to this blog, and everything works now fine.

  4. matt April 9, 2016 at 8:40 pm #

    5 stars blogpost,
    very usefull

    thanks!!

    • Adrian Rosebrock April 13, 2016 at 7:09 pm #

      Thanks Matt! :-)

  5. Dirk Reese May 10, 2016 at 7:10 am #

    Adrian, pyimagesearch and your tutorials totally rock. Absolutely awesome stuff. Python and OpenCV are incredible, and your guidance is such a valuable asset.

    I am confused as to why you put numpy, scipy, and matplotlib in the plotting virtual environment. When I did that it could not find the cv2 module. Which I expected based on my understanding of virtual environments (which is very little). I installed them all in virt env cv3 (OpenCV v3.1.0) and everything works great so far. Am I missing something? Why did your python interpreter find cv2 in the plotting virt env?

    • Adrian Rosebrock May 10, 2016 at 8:03 am #

      I tend to create different virtual environments for each of my projects. Since this blog post was not 100% specific to OpenCV (and users not using OpenCV could have the same problem), I didn’t use the cv virtual environment.

      In reality, you can create and name a virtual environment whatever you want. To get the OpenCV bindings into a name virtual environment, just sym-link the cv2.so (and optionally cv.py) files into the site-packages of the virtual environment — in fact, this is exactly what I did for the plotting virtual environment.

  6. UriMcFly June 8, 2016 at 10:59 am #

    Hi, I’m doing a python project and I’m having a similar issue.

    First of all I was doing this project on a PC-Duino (SO ubuntu 12.04), my code ran fine all the time and my core functions are imread() to read a png image, plt.show() to display this image, and after adding some patches on runtime finally use plt.draw() to see these patches in ‘real-time’.

    Now I need to run this code on a computer.. the image keep displaying after doing plt.show() but it seems that plt.draw has no effect (without warning nor error).. it just does nothing. I have been trying first on my windows10, then i’ve downloaded and installed an ubuntu16 partition with no results..

    I guest it could be a version issue, so i checked my matplotlib version on PC-Duino which is 1.1.1 and the one installed on my computer is 1.5.1, so I downgrade matplotlib to 1.1.1 and then a new issue appears which brings me straightforward to this post: this time the image doesn’t display anymore by doing plt.show().

    Finally I fixed this last issue thanks to you (i was using Agg backend instead of TkAgg) and now restored my matplotlib to 1.5.1 version but i’m unable to make plt.draw() working fine on my computer. This is annoying.

    Any idea?

    Thanks!

    • Adrian Rosebrock June 9, 2016 at 5:23 pm #

      That is quite the strange error! I’m honestly not sure as I don’t use the plt.draw() function, but if I come across anything, I’ll let you know.

  7. XuanToa June 15, 2016 at 8:51 pm #

    Hi Adrian,

    Thanks for this solution.
    However, It only works for grayscale histogram to me. It doesn’t work for color histograms.

    • Adrian Rosebrock June 18, 2016 at 8:28 am #

      This code only computes grayscale histograms. Computing color histograms requires different code. If you haven’t taken a look at Practical Python and OpenCV, I detail how to compute and visualize color histograms in there.

  8. rafael June 24, 2016 at 4:19 pm #

    thanks a lot man, i passed a whole afternoon look for a solution to get a display plot, now your explanation, i got it, thanks.

    • Adrian Rosebrock June 25, 2016 at 1:42 pm #

      Congrats Rafael! :-)

  9. Henk Schuurman July 15, 2016 at 8:49 am #

    on a Raspberry Pi 3 I tried to run this in the python interpreter in (cv); got no errors, but the command:
    plt.figure()
    responses with
    nothing on the screen, so I think it plots beyond the vga memory.
    What to do?

    • Adrian Rosebrock July 15, 2016 at 1:28 pm #

      Very strange, I haven’t ran into that issue before. Can you run matplotlib.get_backend() and see which backend you are using?

  10. vivek borse August 17, 2016 at 9:11 am #

    hi adrian i am using raspberry pi 3 in that cv is a virtual environment, in that environment i can not able to import matplotlib in python how can i solve this?
    I created plotting virtual environment but it doesn’t solve it

    • Adrian Rosebrock August 17, 2016 at 11:57 am #

      If you are using the cv virtual environment, then follow the same steps detailed in this tutorial. Just use:

      $ workon cv

      To access the cv virtual environment instead of the plotting virtual environment.

  11. vivek borse August 29, 2016 at 5:34 am #

    hi Adrian i follow this tutorial in cv environment.so plotting environment is running so that can we use cv and matplotlib in plotting environment?

    • Adrian Rosebrock August 29, 2016 at 1:54 pm #

      Correct, you just need to install matplotlib into the cv virtual environment (or whatever virtual environment name you are using).

Leave a Reply