Stopping the Python rocketship icon
January 15, 2014 at 10:42 PM by Dr. Drang
The stock version of Python that ships with OS X has one very annoying habit: when it thinks it’s doing something involving a graphical user interface, it puts a rocketship icon in the Dock.
There are a couple of things wrong with this:
It’s ugly. The rocketship itself isn’t so bad, but the intertwined snakes are just dropped on top of it with no attempt to match the curvature of the ship.1
Too often, Python thinks there’s GUI stuff going on when there isn’t, so the icon appears for no reason.
In particular, the icon appears up whenever a Python script uses the Matplotlib library. This is particularly vexing to me, because I use GeekTool on my office computer to display a Dark Sky precipitation plot on the Desktop, and the plot is created and updated by a Python/Matplotlib script that runs every ten minutes. So every ten minutes, the rocketship pops up in my Dock for a second or so and then disappears.
I’ve solved this in the past by making an addition to the Info.plist
file that’s in Python.app
bundle. The addition sets the LSUIElement
attribute, which tells OS X that the app shouldn’t appear in the Dock. When I updated my office computer to Mavericks yesterday, the update wiped out my changes and I started seeing the rocketship again.
I thought I’d been clever when I wrote the post with the Dark Sky script, because I’d included a link to a Stack Overflow page that described how to change Info.plist
to prevent the icon from appearing. Unfortunately, that page has been removed or its URL has changed—either way, I couldn’t find it yesterday.2 So I Googled for the answer, and it took a while because I couldn’t remember the name of the attribute—LSUIElment
—I was searching for. Eventually, I found this thread on the Pythonmac-SIG mailing list, which had the answer. Almost.
I say “almost” because apparently Boolean settings in plist files have changed since 2009. The mailing list talks about setting LSUIElement
to 1
, but when I opened Info.plist
, I noticed that Booleans looked like this
<key>LSRequiresCarbon</key>
<true/>
instead of this
<key>LSRequiresCarbon</key>
<string>1</string>
I decided to do the same with LSUIElement
.
So here’s the complete set of instructions for stopping the Python rocketship icon from appearing in the Dock.
Navigate to
/System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/
If you do this from the Terminal, you can just
cd
to that directory. If you go folder-by-folder in the Finder, you’ll have to right-click onPython.app
and choose from the popup menu.Open
Info.plist
. This is a binary file, but some text editors, like BBEdit, are smart enough to be able to edit even binary plist files, presumably by runningplutil
in the background. BBEdit is also smart enough to ask you for an administrator password so you can edit and save the file.If your text editor isn’t as smart as BBEdit, you can do the conversion from binary to text with this command:
sudo plutil -convert xml1 Info.plist
And you can change the file’s permissions so you can edit it with this:
sudo chmod 666 Info.plist
You’ll be asked for an administrator password with the first
sudo
.(Obligatory responsible adult advice: if you don’t know what
sudo
is, you probably shouldn’t be doing any of this.)The editing itself is the easy part. Add the following lines just before the final
</dict>
near the end of the file,<key>LSUIElement</key> <true/>
and then save the file.
If necessary, change the permissions back to what they were:
sudo chmod 644 Info.plist
Then convert back to binary:
sudo plutil -convert binary1 Info.plist
If you have Xcode installed, you can use it to open Info.plist
and add the LSUIElement
entry. I find Xcode to be a pain in the ass for plist editing, so I can’t give you step-by-step instructions for using it. Sorry.
You’ve probably guessed that this post is more for my benefit than yours. I don’t want to have to hunt down the solution again, and I’ve learned from the unfortunate Stack Overflow incident not to trust other sites. With luck, I’ve loaded this article with enough obvious search terms—Python, rocket, rocketship, Dock, icon—to make it easy for me to find the next time an OS X update overwrites my changes.
Update 1/16/14
Reader David Hall informs me by email that the rocketship icon can be suppressed in scripts that use Matplotlib without any plist editing. Instead of just
import matplotlib.pyplot as plt
at the top of your script, use
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
It’s important that the two new lines go before the line that imports pyplot
.
Agg
is one of Matplotlib’s noninteractive backends, and is intended for bitmapped output. For vector output, you could use the PS
, PDF
, or SVG
backends. Whichever backend you choose, as long as you choose a noninteractive one, Python will not expect any GUI features and will not trigger the rocketship icon.
In keeping with Matplotlib’s interesting approach to documentation, the issue of backends isn’t found in the example code or in any of the documentation new users are directed to. It’s in the Usage section of the FAQ, which I had never thought to look in until David’s email. That’s also where you’ll learn that the default backend for OS X installations of Matplotlib is macosx
, which is interactive and is the reason for the rocketship.
In fact, installations of Matplotlib on all platforms use one of the interactive backends by default. Most of them will pop up a terminal window when you start issuing pyplot
commands unless you’ve chosen a noninteractive backend through matplotlib.use
.
If you do a lot of interactive plotting via IPython, you can suppress the rocketship automatically by including the matplotlib.use
command in your ipythonrc
file. Yes, you can tell Matplotlib to be noninteractive for interactive sessions. That’s because software is all logical and shit.
Personally, I’m sticking with the LSUIElement
solution because it suppresses the rocketship under all conditions, not just when I use Matplotlib. But David pointed out a situation in which the matplotlib.use
solution is the way to go: when you’re rendering a plot on a remote Unix/Linux server, that server will, by default, want to bring up X Windows unless you’ve told it to use a noninteractive backend.
-
Let’s not get into the fact that Python isn’t named after the snake, or that even if it were, that intertwined snake symbol is amateurish at best. It’s Exhibit A for the Fleishman argument that programmers (he mistakenly calls them engineers, but that’s because he suffers from the worst aspects of the journalistic mindset) have no sense of style. ↩
-
There is a special place in Hell for those who delete useful pages or fiddle with their URLs. It breaks the Internet, and the Stack Overflow people should know better. ↩