Moving Collections Between Axes

During playback with the ImportanceOfBeingErnest code to move artists between axes, I thought it was easy to expand it to collections (e.g. PathCollectionsgenerated ones plt.scatter) as well. No such luck:

import matplotlib.pyplot as plt
import numpy as np
import pickle

x = np.linspace(-3, 3, 100)
y = np.exp(-x**2/2)/np.sqrt(2*np.pi)
a = np.random.normal(size=10000)

fig, ax = plt.subplots()
ax.scatter(x, y)

pickle.dump(fig, open("/tmp/figA.pickle", "wb"))
# plt.show()

fig, ax = plt.subplots()
ax.hist(a, bins=20, density=True, ec="k")

pickle.dump(fig, open("/tmp/figB.pickle", "wb"))
# plt.show()

plt.close("all")

# Now unpickle the figures and create a new figure
#    then add artists to this new figure

figA = pickle.load(open("/tmp/figA.pickle", "rb"))
figB = pickle.load(open("/tmp/figB.pickle", "rb"))

fig, ax = plt.subplots()

for figO in [figA, figB]:
    lists = [figO.axes[0].lines, figO.axes[0].patches, figO.axes[0].collections]
    addfunc = [ax.add_line, ax.add_patch, ax.add_collection]
    for lis, func in zip(lists, addfunc):
        for artist in lis[:]:
            artist.remove()
            artist.axes = ax
            # artist.set_transform(ax.transData) 
            artist.figure = fig
            func(artist)

ax.relim()
ax.autoscale_view()

plt.close(figA)
plt.close(figB)
plt.show()

gives

enter image description here

Deleting artist.set_transform(ax.transData)(at least during a call ax.add_collection) seems to help a little, but note that the y offset is still disabled: enter image description here How do I move collections from one axis to another?

+4
source share
1 answer

Scatter has an IdentityTransform as its primary transformation. Data conversion is an internal bias. Therefore, it would be necessary to consider the scatter separately.

from matplotlib.collections import PathCollection
from matplotlib.transforms import IdentityTransform

# ...

if type(artist) == PathCollection:
    artist.set_transform(IdentityTransform())
    artist._transOffset = ax.transData
else:
    artist.set_transform(ax.transData) 

, set_offset_transform, ._transOffset.

enter image description here

+1

Source: https://habr.com/ru/post/1693951/


All Articles