9
votes

I'm hoping to setup a method which can convert a normal figure (dark lines, white/transparent background) to a pseudo-inverted figure (light lines, black/transparent background). I could just post-process invert the image, but directly inverted colors look awful, so I'd like to instead (try to) create a mapping from one set of colors to another, and then apply this to all artists which have been added to (all axes on) a figure.

Is there a way to access all objects (e.g. text, scatter, lines, ticklabels, etc) that have been added to a figure?


Edit: my motivation is to automatically create white-background and black-background versions of figures. White-background figures will always (I think) be required for publications (for example), while black-background figures may be better for presentations (i.e. talk slides). While it wouldn't be that much trouble to setup a flag, and change each color based on that, e.g.

if dark:
    col_line = 'cyan'
    col_bg = 'black'
else:
    col_line = 'red'
    col_bg = 'white'

# ... plot ...

It would be much cooler and more convenient (despite overhead) to do something like,

fig.savefig('dark.pdf')
invert(fig)
fig.savefig('light.pdf')
2
This sounds a bit like a workaround solution for something else. If you want to have a cherry cake you wouldn't prepare an apple pie and exchange all apples for cherries; same here: why not make sure the objects are already created with the correct properties? - ImportanceOfBeingErnest
@ImportanceOfBeingErnest because I want to have both versions of a figure without having to replot everything manually, changing parameters as needed (though, that may end up being the best/easiest solution). I've added some clarification on the question. - DilithiumMatrix

2 Answers

6
votes

Recursively call .get_children(), stop when the returned list is empty.

2
votes

You can use a different style or change an existing style to your needs instead of changing all properties of all possible artists yourself.

E.g. you might start with the "dark_background" style and then adjust some further parameters using rcParams.

import numpy as np
import matplotlib.pyplot as plt
plt.style.use("dark_background")

style = {"lines.linewidth" : 2,
         "axes.facecolor" : "#410448"}
plt.rcParams.update(style)

plt.plot(np.sin(np.linspace(0, 2 * np.pi)))

plt.show()

enter image description here