matplotlib

How do I change the color of the axes of a matplotlib 3D plot?


I have set

import matplotlib as mpl
AXES_COLOR = '#333333'
mpl.rc('axes', edgecolor=AXES_COLOR, labelcolor=AXES_COLOR, grid=True)
mpl.rc('xtick', color=AXES_COLOR)
mpl.rc('ytick', color=AXES_COLOR)
mpl.rc('grid', color=AXES_COLOR)

The color of the axes labels and the ticks are properly set both in 2D and in 3D. However, the edgecolor doesn't apply to 3D axes and they remain black. Likewise, the grid isn't affected.

I think figured out how to access the individual axes of a 3D plot:

import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d # Needed for 3d projection.
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.w_zaxis # <- the z axis

The documentation mentions a property that we can use until the developers have finished refactoring their 3D code:

import pprint
pprint.pprint(ax.w_xaxis._AXINFO)

{'x': {'color': (0.95, 0.95, 0.95, 0.5),
       'i': 0,
       'juggled': (1, 0, 2),
       'tickdir': 1},
 'y': {'color': (0.9, 0.9, 0.9, 0.5),
       'i': 1,
       'juggled': (0, 1, 2),
       'tickdir': 0},
 'z': {'color': (0.925, 0.925, 0.925, 0.5),
       'i': 2,
       'juggled': (0, 2, 1),
       'tickdir': 0}}

However, the color parameter changes the color of the background of the axes planes (between the wired of the grid), not the color of the edges of these planes.

Am I digging too deep ?


Solution

  • Turns out it's impossible since these values are hard-coded. This archived email from the matplotlib-users mailing list helped me. Here's the relevant part:

    Unfortunately, you have stumbled upon one of the ugliness of the mplot3d implementation. I am hoping to have more control available for the next release. But right now, there is no way to turn off the axes spines (because they aren't implemented as spines). If you really want to dig into the source code, you could change the color argument to the Line2D call in the init3d() method in matplotlib/lib/mpl_toolkits/axis3d.py

    Although this answer was addressing another concern, it sent me to the direction of axis3d.py. I found it in /usr/lib/pymodules/python2.7/mpl_toolkits/mplot3d. I made a backup of the original axis3d.py and I moved axis3d.pyc away.

    Since the code is pretty short and fairly well written it didn't take long to locate the two lines I had to change.

    And that's it, it just works. Not the most convenient, but it's not more work than editing a rc configuration file.

    I did not recreate a .pyc file. It does not recreate itself because I do not run my python code as root. I don't mind the extra milliseconds that python needs to recompile the .py each time.