Reputation: 2695
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 ?
Upvotes: 2
Views: 7332
Reputation: 198
For posterity, here is a method to change each individual axis color, the grid color, the tick color and the tick label colors.
import numpy as np
from matplotlib import pyplot as plt
# Grid color (here in RGBA, also named colors as strings work)
plt.rcParams['grid.color'] = (0.5, 0.5, 0.5, 0.2)
# Figure
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.scatter(np.random.rand(10),np.random.rand(10),np.random.rand(10))
# Axes colors
ax.xaxis.line.set_color('C1')
ax.yaxis.line.set_color('C2')
ax.zaxis.line.set_color('C3')
# Tick colors
ax.tick_params(axis='x', colors='C4')
ax.tick_params(axis='y', colors='C5')
ax.tick_params(axis='z', colors='C6')
# Label colors
for i,tick in enumerate(ax.get_xticklabels()):
tick.set_color(f"C{i}")
for i,tick in enumerate(ax.get_yticklabels()):
tick.set_color(f"C{i+1}")
for i,tick in enumerate(ax.get_zticklabels()):
tick.set_color(f"C{i+2}")
# Show
plt.show()
I'm not sure if it's possible to change each individual tick color, the method from 2d plots (for example here) does not work. Answers taken from here for axis color, here for grid color, here for tick color, here for tick label color.
Upvotes: 0
Reputation: 59
Instead of changing axis3d.py try this: ax.w_xaxis.line.set_color("red")
Upvotes: 5
Reputation: 2695
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.
self.line=...
in __init__
: just replace color=(0, 0, 0, 1)
by color=(1, 0, 0, 1)
for a horribly flashy red. Components of the tuple are red, green, blue, alpha, all floats from 0 to 1.draw
method. I replaced the color self.gridlines.set_color([(0.9,0.9,0.9,1)] * len(lines))
by something of my choosing.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.
Upvotes: 2