7

This is a question linked to this well received one. In that question I see an answers on how to plot images (or different images) at different coordinates like a scatter plot.

Using TextArea I can put little strings instead of images at different coordinates.

How about if I want to put a mini version of a plot/image generated by matplotlib itself? Suppose I want instead of using an image.jpg I want to use the result of plt.stem(arr) as the image in the scatter plots.

How can I do this? How about a miniature version of the output of plt.plot(x, y)?

I tried modifying the function given in the linked question to be like:

def stem_scatter(x, y, arr, ax=None):

    from matplotlib.offsetbox import AnnotationBbox, DrawingArea

    if ax is None:
        ax = plt.gca()
    im = DrawingArea(0.1, 0.1)
    im.add_artist(plt.stem(arr))
    x, y = np.atleast_1d(x, y)
    artists = []
    for x0, y0 in zip(x, y):
        ab = AnnotationBbox(im, (x0, y0), xycoords='data', frameon=False)
        artists.append(ax.add_artist(ab))
    ax.update_datalim(np.column_stack([x, y]))
    ax.autoscale()
    return artists

But that gives an error: AttributeError: 'StemContainer' object has no attribute 'is_transform_set'

EDIT: From the linked question:

"…. but the second has a large advantage. The annotation box approach will allow the image to stay at a constant size as you zoom in."

this would be a desirable feature in an accepted answer because on zooming in one would like to see the relative positions of the scatter points. If the scatter plotted image did not maintain a fixed size (relative to the screen as opposed to current axis limits), then zooming in would be of little help.

ITA
  • 3,200
  • 3
  • 18
  • 32
  • A bit hacky, but you can use `plt.savefig` to save a picture, then use the method in the linked question – BlackBear May 31 '19 at 08:57
  • @BlackBear Indeed that (or a variation of that using PIL to avoid saving to disk) is what I am currently doing … but if you have a scatter plot with a couple of hundred points it doesn't seem like the best way. – ITA May 31 '19 at 09:01
  • You already got an answer by one of the matplotlib developpers. What is the bounty for? Did you try using an inset axes? – ImportanceOfBeingErnest Jun 01 '19 at 01:24
  • @ImportanceOfBeingErnest I am not sure it is really an answer, rather more of a suggestion in a possible direction … which may or may not work. And ... no I didn't try, mostly because the link in the answer features a prominent warning that the feature is experimental and the API may change. – ITA Jun 01 '19 at 07:19
  • Also from the linked question: "…. but the second has a large advantage. The annotation box approach will allow the image to stay at a constant size as you zoom in.". I am not completely sure, but my experiments suggested this is not true for a naive `inset_axes` approach. – ITA Jun 01 '19 at 07:36
  • You could use `mpl_toolkits.axes_grid1.inset_locator.inset_axes` instead, which is not experimental, and which offers slightly more features. See [the demo](https://matplotlib.org/gallery/axes_grid1/inset_locator_demo.html). In [this question](https://stackoverflow.com/questions/46262749/plotting-scatter-of-several-polar-plots) something similar is shown. If a specific zooming / panning behaviour is required please explain it inside the question. – ImportanceOfBeingErnest Jun 01 '19 at 10:16
  • So did you try the inset_axes? Did you experience any problem? Is there something missing from the example that I should add? – ImportanceOfBeingErnest Jun 12 '19 at 02:28

1 Answers1

1

You could try something like: https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.inset_axes.html

Jody Klymak
  • 4,979
  • 2
  • 15
  • 31