When no keyword argument does what you need, walking the Artist tree lets you change any detail of any chart, including those made by pandas or seaborn.
Everything drawn in Matplotlib is an Artist. The tree looks like this:
Figurecontains Axes, figure-level text, legends and patches (the backgroundfig.patch).Axescontains its twoAxisobjects (withTicks, which holdLine2Dtick marks andTextlabels),spines, the title texts and the data artists inax.lines,ax.patches,ax.collections,ax.imagesandax.texts.
Primitives are Line2D, Rectangle and other Patches, Text, AxesImage and Collections (many similar shapes drawn efficiently, as scatter returns). Containers (Figure, Axes, Axis, Tick) hold other artists.
Every Artist shares an interface: get_*/set_* properties, set(**kwargs) for several at once, set_visible, set_zorder (drawing order), set_alpha, set_clip_on, get_children() and findobj(match) to search the subtree. plt.getp(artist) lists all properties, a quick way to discover what is settable.
Plotting helpers are just factories: ax.bar creates Rectangle patches and adds them with ax.add_patch. You can do the same, building custom shapes with matplotlib.patches and adding them yourself.
Artists only describe what to draw; nothing is rendered until the canvas draws the figure, calling each artist's draw(renderer) in z-order. That is why some values, such as text extents or automatic tick labels, are only accurate after fig.canvas.draw().
Example
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.text import Text
fig, ax = plt.subplots()
ax.bar(["a", "b", "c"], [3, 5, 2])
ax.set_title("Sales")
print(type(ax.patches[0]).__name__, len(ax.patches)) # Rectangle 3
ax.patches[1].set(color="tab:red", hatch="//") # restyle one bar
ax.add_patch(Rectangle((-0.5, 4), 3, 0.1, color="gray", alpha=0.5))
texts = fig.findobj(Text)
print(any(t.get_text() == "Sales" for t in texts)) # True
for s in ("top", "right"):
ax.spines[s].set_visible(False)
print([type(c).__name__ for c in ax.get_children()][:4])
# ['Rectangle', 'Rectangle', 'Rectangle', 'Rectangle']
fig.savefig("artists.png")Remember
- Every drawn element is an Artist in a tree rooted at the Figure
- All Artists share get/set properties, visibility, z-order and
findobj - Plot functions create primitives you can later restyle or add yourself
Watch out for
- Reading text sizes or tick labels before the figure has been drawn, and getting placeholder values.