0

optional context feel free to skip: I'm currently using cartopy and matplotlib to read in and plot weather model data on a map. I have three different fields I'm plotting: temperature, wind, and surface pressure. I'm using contourf, barbs, and contour respectively to plot each field. I want one image for each field, and then I'd like one image that contains all three fields overlaid on a single map. Currently I'm doing this by plotting each field individually, saving each of the individual images, then replotting all three fields on a single ax and a new fig, and saving that fig. Since the data takes a while to plot, I would like to be able to plot each of the single fields, then combine the axes into one final image.

I'd like to be able to combine multiple matplotlib axes without replotting the data on the axes. I'm not sure if this is possible, but doing so would be a pretty major time and performance saver. An example of what I'm talking about:

from matplotlib import pyplot as plt
import numpy as np
x1 = np.linspace(0, 2*np.pi, 100)
x2 = x1 + 5
y = np.sin(x1)

firstFig = plt.figure()
firstAx = firstFig.gca()
firstAx.scatter(x1, y, 1, "red")
firstAx.set_xlim([0, 12])
secondFig = plt.figure()
secondAx = secondFig.gca()
secondAx.scatter(x2, y, 1, "blue")
secondAx.set_xlim([0, 12])

firstFig.savefig("1.png")
secondFig.savefig("2.png")

This generates two images, 1.png and 2.png.

1.png

2.png

Is it possible to save a third file, 3.png that would look something like the following, but without calling scatter again, because for my dataset, the actual plotting takes a long time?

3

Reti43
  • 9,656
  • 3
  • 28
  • 44

1 Answers1

0

If you just want to save images of your plots and you don't intend to further use the Figure objects, you can use the following after saving "2.png".

# get the scatter object from the first figure
scatter = firstAx.get_children()[0]
# remove it from this collection so you can assign it to a new axis
# the axis reassignment will raise an error if it already belongs to another axis
scatter.remove()
scatter.axes = secondAx
# now you can add it to your new axis
secondAx.add_artist(scatter)
secondFig.savefig("3.png")

This modifies both figures, as it removes a scatter from one and adds it to another. If for some reason you want to preserve them, you can copy the contents of secondFig to a new one and then add the scatter to that. However, this will still modify the first plot as you have to remove the scatter from there.

Reti43
  • 9,656
  • 3
  • 28
  • 44
  • so thanks for the response, this basically confirms for me that something like this is possible, but unfortunately it doesn't seem to work perfectly. Specifically the scaling doesn't work properly. https://i.imgur.com/FIXCGqO.jpg Over the past few days I've tried learning about transformations on my own (and I haven't given up yet...), but I wanted to know if you knew how to fix this. [code](https://paste.bingner.com/paste/d54jf) – Sam Gardner Dec 18 '21 at 02:59
  • @SamGardner I have no idea how you generated that result. Your initial dataset + the code in my answer can produce your desired result. If this red line is a different sine wave, e.g., scaled or shifted, it's possible it's outside the [-1, 1] range in the y axis. In that case you'd need to set new limits for the axes to see the whole curve. You can try `y0, y1 = firstAx.get_ylim(); y2, y3 = secondAx.get_ylim(); secondAx.set_ylim(min(y0, y2), max(y1, y3))`. And same for the x-axis limits. – Reti43 Dec 18 '21 at 03:11
  • hmm, so this is really strange, running the exact same code on linux generates the plot I want, but running it on my mac does the weird shifting thing. I'll do more testing and try to figure out why, but thanks so much for the help! – Sam Gardner Dec 18 '21 at 03:55
  • @SamGardner Long shot, but I believe mac uses a different backend by default and it may be the culprit. Check it with `matplotlib.get_backend()` and change it with `matplotlib.use()`. See the [docs](https://matplotlib.org/stable/api/matplotlib_configuration_api.html#matplotlib.use) for a list of backends. Try TkAgg if possible. – Reti43 Dec 18 '21 at 12:17