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):
Since we are using matplotlib, let’s create a new virtual environment called plotting
:
$ mkvirtualenv plotting
Now that we’re in the plotting
environment, let’s install numpy
, scipy
, and matplotlib
:
$ pip install numpy $ pip install scipy $ pip install 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
:
# import the necessary packages from matplotlib import pyplot as plt import cv2 # load the image, convert it to grayscale, and show it image = cv2.imread("raptors.jpg") gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) cv2.imshow("Image", image) cv2.imshow("Gray", gray) cv2.waitKey(0) # construct a grayscale histogram hist = cv2.calcHist([gray], [0], None, [256], [0, 256]) # plot the histogram plt.figure() plt.title("Grayscale Histogram") plt.xlabel("Bins") plt.ylabel("# of Pixels") plt.plot(hist) plt.xlim([0, 256]) plt.show() cv2.waitKey(0)
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:
$ python grayscale_histogram.py
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:
However, when I go over to my Ubuntu 14.04 machine and execute the exact same code all I see are my images:
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()
:
$ python Python 3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import matplotlib >>> matplotlib.get_backend() 'agg'
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:
$ sudo apt-get install tcl-dev tk-dev python-tk python3-tk
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 viaworkon 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 usingsetup.py
.
I can accomplish these steps using the following commands:
$ workon plotting $ pip uninstall matplotlib $ git clone https://github.com/matplotlib/matplotlib.git $ cd matplotlib $ python setup.py install
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:
$ python Python 3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import matplotlib >>> matplotlib.get_backend() 'TkAgg'
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:
$ python grayscale_histogram.py
We should now see both our grayscale image along with our histogram:
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:
$ sudo apt-get install python-matplotlib
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.
What's next? We recommend PyImageSearch University.
86 total classes • 115+ hours of on-demand code walkthrough videos • Last updated: October 2024
★★★★★ 4.84 (128 Ratings) • 16,000+ Students Enrolled
I strongly believe that if you had the right teacher you could master computer vision and deep learning.
Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?
That’s not the case.
All you need to master computer vision and deep learning is for someone to explain things to you in simple, intuitive terms. And that’s exactly what I do. My mission is to change education and how complex Artificial Intelligence topics are taught.
If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to successfully and confidently apply computer vision to your work, research, and projects. Join me in computer vision mastery.
Inside PyImageSearch University you'll find:
- ✓ 86 courses on essential computer vision, deep learning, and OpenCV topics
- ✓ 86 Certificates of Completion
- ✓ 115+ hours of on-demand video
- ✓ Brand new courses released regularly, ensuring you can keep up with state-of-the-art techniques
- ✓ Pre-configured Jupyter Notebooks in Google Colab
- ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
- ✓ Access to centralized code repos for all 540+ tutorials on PyImageSearch
- ✓ Easy one-click downloads for code, datasets, pre-trained models, etc.
- ✓ Access on mobile, laptop, desktop, etc.
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!
Join the PyImageSearch Newsletter and Grab My FREE 17-page Resource Guide PDF
Enter your email address below to join the PyImageSearch Newsletter and download my FREE 17-page Resource Guide PDF on Computer Vision, OpenCV, and Deep Learning.
Thomas Caswell
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
You can control the backend via the
.matplotlib
file and thematplotlib.use()
function. However, that will not help if the backend is not actually installed. The most important step is to grab the dependencies viaapt-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.Hilman
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
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
Yes. I believe it is because of the virtual environment has some conflicts with the matplotlib.
Adrian Rosebrock
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
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
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
Like this? :
https://gist.github.com/hilman-dayo/39648eb29704ab560c47
Adrian Rosebrock
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.
Mootaz
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.
matt
5 stars blogpost,
very usefull
thanks!!
Adrian Rosebrock
Thanks Matt! 🙂
Dirk Reese
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
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 optionallycv.py
) files into thesite-packages
of the virtual environment — in fact, this is exactly what I did for the plotting virtual environment.UriMcFly
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
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.Prashant Dandriyal
I may be too late to reply to this already resolved issue, but I believe that people like me really appreciate your efforts Adrian and would eventually, come here for a similar issue related to “Unable to plot using matplotlib on windows 10”
This is how I worked it out …
In my case (Windows 10 + python 3.7), just after
import matplotlib
I had to change the environment from ‘Agg’ to ‘TkAgg’ using
matplotlib.use(‘TKAgg’,warn=False, force=True)
right before the code where I actually plotted, i.e,
import matplotlib.pyplot as plt
fig = plt.figure()
# AND SO ON….
Adrian Rosebrock
Thanks for sharing!
XuanToa
Hi Adrian,
Thanks for this solution.
However, It only works for grayscale histogram to me. It doesn’t work for color histograms.
Adrian Rosebrock
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.
rafael
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
Congrats Rafael! 🙂
Henk Schuurman
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
Very strange, I haven’t ran into that issue before. Can you run
matplotlib.get_backend()
and see which backend you are using?vivek borse
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
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 theplotting
virtual environment.vivek borse
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
Correct, you just need to install matplotlib into the
cv
virtual environment (or whatever virtual environment name you are using).bert
You saved the day Adrian,
I wasn’t able to see the plot at first but remembered reading this post after which the plot showed up nicely.. Thanks!
Adrian Rosebrock
Fantastic, I’m happy to hear it Bert!
Dumitru Popa
Hello, it is posible to include image near histogram in Tkinter ? Thank you.
Adrian Rosebrock
Hi Dumitru — can you elaborate on what you mean by “include image near histogram in TKinter”? Are you trying to display an image inside a matplotlib plot?
Aku Putri
When i install matplotlib in opencv
Collecting matplotlib
Downloading matplotlib-2.0.0.tar.gz (53.2MB)
…
MemoryError
Adrian Rosebrock
Try using the
--no-cache-dir
option:$ pip install matplotlib --no-cache-dir
Putri
hi adrian i am using raspberry pi 3, opencv3, and python 2.7.9
>>> matplotlib.get_backend()
u’TkAgg’
bu i still cant showing histogram
What should i do??
Adrian Rosebrock
How are you accessing your Raspberry Pi? Over SSH and VNC? Or via a connected keyboard + HDMI monitor?
Zaso
Hi adrian,im using same setup and backend GTk3Agg and figure is white but when i go over with cursos,i can see x,y values. im on monitor via hdmi on Raspberry 3 Pi
Adrian Rosebrock
Hi Zaso — that is indeed strange, I’m sorry to hear about the matplotlib issue. However, I must admit that I’m not sure what the exact error is. I would suggest posting on the GitHub Issues page for the matplotlib repo.
Leonardo
Hi Adrian, first of all I would like to congratulate with you for this useful blog.
I have an issue about visualising image and related histogram:
I can’t see them simultaneously, I mean histogram window pops up only when I have closed the images window.
Do you know how can I solve it and show them together as your tutorial does?
Thanks in advance
Adrian Rosebrock
The matplotlib call will block execution of the script until you close the window. Call
cv2.imshow
beforeplt.show
and it should resolve the issue.Rogeri
Thanks for your post, It saves me a lot of time.
Adrian Rosebrock
Thanks Rogeri, I’m glad to hear it 🙂
Toshio Futami
Hi Dr.Adrian Rosebrock
I have succeeded to install OpenCV3 into RasPi3 according to your instruction.
And also succeeded to execute the grayscale_histogram.py.
But unfortunately I haven’t succeeded to install scipy until now.
Monitor show only “Runnig setup.py bdist_wheel for scipy” for long time.
Would you help me how to install scipy into my RasPi3?
Adrian Rosebrock
Installing SciPy on the Raspberry Pi will take quite a bit of time. I would suggest starting the install and letting it run overnight.
Alex C
Thanks a lot for the post – very helpful! I ended up simply needing to change the backend by using rcParams.update(), but until I saw this post I had no idea where to start to make my figure appear!
Adrian Rosebrock
Congrats on resolving the matplotlib issue, Alex!
Elias
Thanks for your great tutorials! I followed the instructions, but I am getting an error/warning after installing matplotlib from Github on the Raspberry Pi 3 Model B+. In the cv virtualenv I type
python
>>> import matplotlib
The result is
“UserWarning: could not find rc file; returning defaults.”
Now I am trying
>>> matplotlib.get_backend()
‘agg’
The matplotlibrc file seems to be not created at installation, because there is no file in ‘/home/pi/.config/matplotlib/’. Do you know how to fix this problem? I tried to copy the matplotlibrc.template file from the Git to this directory but without success.
Thank you for your answer.
Elias
I solved the problem by copying the matplotlibrc.template file to ‘/home/pi/.virtualenvs/cv/lib/python3.5/site-packages/matplotlib-2.2.2+1059.g8a29c4059-py3.5-linux-armv7l.egg/matplotlib/mpl-data’ which was the result of
>>> matplotlib.matplotlib_fname()
.
Furthermore I had to change the filename to ‘matplotlibrc’ and line 40 (in my case) of its code to
backend : TkAgg
Nevertheless it would be interesting why there is no rc file added automatically.
Adrian Rosebrock
Thanks for sharing the solution, Elias! 🙂
Liujie
hi, Adrian.
When I run mkvirtualenv cv2 this command , it’s point that command can not found. so I use pip to install virtualenv and virtualenvwrapper , it didn’t successful, and it’s also point that matplotlib 2.2.2 has requirement numpy >=1.7.1, but you’ll have numpy 1.6.1 which is incompatible . I failed to upgrade numpy1.6.1 to 1.7.1.
Can you give me some advice ? Thank you
Adrian Rosebrock
Hey Liujie — you mentioned that both virtualenv and virtualenvwrapper failed to install. I would suggest starting there and resolving that issue before you move forward.
Sruthi
Hi Adrian,
When I do matplotlib.get_backend(),
I get ‘TkAgg’
But still I couldn’t get the plots
So I uninstalled and reinstalled matplotlib after installing the dependencies as you suggested, but still no plot.
I am using ubuntu 16.04, python 3.5.2.
Adrian Rosebrock
Which version of matplotlib do you have installed currently?
Sruthi
Hi Adrian,
When I do matplotlib.get_backend(),
I get ‘TkAgg’
But still I couldn’t get the plots
So I uninstalled and reinstalled matplotlib after installing the dependencies as you suggested, but still no plot.
I am using ubuntu 16.04, python 3.5.2.
matplotlib.__version__ gives version as ‘2.2.2+1330.gaf7a74b’
Adrian Rosebrock
Can you try using an older version of matplotlib and see if that resolves the issue?
Rin
Hi Adrain! Thanks alot for helping us with our questions. I have the same issue has Sruthi and installing the older version of matplotlib didn’t help. Also, I’m trying to run cocoapi and the pycocotools im using requires matplotlib>2.0. May I ask what other options I have? Thanks!
Adrian Rosebrock
I don’t have a lot of experience with the pycocotools library so I’m honestly not sure what their dependencies are or what they are trying to do with matplotlib. I would suggest posting on their GitHub issues page.
Rin
Hi Adrain,
Thanks alot for this article! My issue is, I have this line: pycocotools.coco import COCO. And from terminal:
The backend was *originally* set to ‘agg’ by the following code:
File “coco0309.py”, line 3, in
from pycocotools.coco import COCO
I tried inserting the line matplotlib.use(“TkAgg”) before that line and then after that line as well but both didn’t work.
When I:
print(plt.get_backend())
print(matplotlib.get_backend())
I get:
agg
agg
Is it possible to do this without using TkAgg? Thanks alot for doing this for us!!!
KVS Setty
Hello Adrain,
Thanks for the tutorial,
Here I would like to share a different experience here I had, the ran the above script on my Windows system and didn’t get the display of histogram and
first I thought the problem is similar to Linux system, but after making the gray scale image and tapping some key, the histogram window displayed, then I realized that the reason is because of the waitKey(0) command , which did not
allow the execution of the code further down till I tap some key. And I was laughing out myself for my first thoughts ( ie ,thinking some issues similar to Linux and I am going to have a tough time to resolve, thank God , nothing like that required ).
I really appreciate your time effort in making such wonderful tutorials and making me to think for next system (third one) to be a Linux. By the way
right now, I work on both Windows and Mac Pro systems and shortly a Linux system will added and this is going to be used only for ML and DL projects on the domains like CV, NLP, Speech and Data Analytics.
And you are the main inspiration to enter in to this field of AI, especially
DLforCV.
Thanks a lot again.
Adrian Rosebrock
Thanks for sharing! I also really appreciate your kind words. Keep up the great work! 🙂
Satya
How did you ever track this down. Great job.
unnanmed
Thanks a lot for posting this.
Adrian Rosebrock
You are welcome!
cumlouder
Thanks,As you said,matplotlib figures not showing up or displaying generally on my system,this problem has been solved and can be used normally.
Bojan Komazec
Many thanks for this post Adrian. I just wanted to share my experience with matplotlib in venv.
I followed the instructions but didn’t manage to make the latest matplotlib (3.2.0rc2+1298.g58c66982d) to use GTK3Agg in virtual env. I tried both installing from source and via pip, matplotlib.get_backend() would always return agg. But as soon as I installed matplotlib version you suggested (1.4.3, via pip), it started picking up GTK3Agg backend and showing UI windows. I am on Ubuntu 18.04, using Python 3.6 in virtual env.
Adrian Rosebrock
Thanks for sharing, Bojan!
Akshay
I was trying to do mask rcnn and then do the inference. I checked the matplotlib.get_backend() in the begining(before evaluation of the model). The output was ‘Qt5Agg’. After running the evaluation part, ith automatically changed to ‘agg’. How to resolve this?
Kishor
HI Adrian,
Awesome, thanks for the explanation.
I just want to know if the similar approach can be implemented in Docker environment to pop up the matplotlib plots.
I have been trying to do some plotting inside a docker container, since docker container is headless (no GUI) I am not able see any plots. I can save the plotted images, however I would like to see it instantly as I am planning for dynamic plot.
Thank you,
Kishor