Search code examples
pythonmatplotlibjupyter-notebookseabornseaborn-objects

Duplicate plots are output when using seaborn.objects with subplots in jupyter


I am running the code in jupyter, which displays a plot figure. However, without plt.show(), the same plot is duplicated, so two plot figures are display. Why is this happening?

import matplotlib.pyplot as plt
import seaborn as sns
import seaborn.objects as so

diamonds = sns.load_dataset("diamonds")

f, (ax1, ax2) = plt.subplots(1, 2, sharey=True, figsize=(6, 3))

p = so.Plot(diamonds, x="carat", y="price")
p.add(so.Dots()).scale(y="log").on(ax1).plot()
p.add(so.Dots(), color="clarity").scale(color="crest").on(ax2).plot()
plt.show()

Output without plt.show()

enter image description here


Solution

  • You're seeing this because you're both returning the Plot from the cell and using the matplotlib-inline pyplot backend.

    When a Plot object is returned from the last line in a Jupyter Notebook cell, it will be rendered and displayed in the cell output through Jupyter's rich display system. You can also call display(p) to hook into the same mechanism.

    Separately, because you're using the matplotlib-inline pyplot backend (implicitly; it is Jupyter's default), any pyplot figures created by the cell will be captured and added to the cell output.

    These are completely different mechanisms and don't know about each other.

    As you've noticed, adding plt.show to the end of the cell disables the first mechanism, because the Plot is no longer "returned" from the cell. It does not actually matter whether you call plt.show or anything else (although plt.show is a good one because it has no return value, so it doesn't add anything else to the cell output). You could also "catch" the final plot (e.g. _ = p.add(...)) or add a trailing semi-colon, similar to how you would disable other cell outputs.

    Alternatively, you could call plt.close to disable the second mechanism. But if you just made plt.close the final line of the cell, you wouldn't see any plots at all, for the reason given in the previous paragraph. You'd need to make sure to display the Plot too.

    You might notice that the two images have different sizes / resolutions. The images that Plot generates through the first mechanism (rich display) use hi-dpi ("retina") scaling by default, so that is a factor to consider when deciding which you want to keep.