2

I have a function which plots and displays the distribution using the distplot from seaborn. it looks like this

def getPlot(data):
    x=sns.distplot(data, hist=False)
    plt.show()
    return x

every time I call the function I get a plot of the distribution.

I want some help in modifying the function so that at the end of calling the function multiple times I should get an extra plot which is the combination of all the previous plots.

So if my function calls were

getPlot(data1)
getPlot(data2)
getPlot(data3)

I should get the individual plots for the data as I call the function and also at the very end I want the plots for the 3 data to be superimposed on each other.

Just moving plt.show() outside the function will not suffice because I want individual plots of the separate data as well as one figure that contains all the data.

a_parida
  • 606
  • 1
  • 7
  • 26
  • What do you mean "at the very end"? Each call to `getPlot` does not know whether there will be more calls or not. – Stop harming Monica Aug 09 '19 at 10:07
  • @Goyo I just want the plot to be accumulated. I can just call `plt.show()` at the end to get the final plot. – a_parida Aug 09 '19 at 10:10
  • You have already called `plt.show()` inside `getPlot` and closed the figures so an additional call would have nothing to show. Maybe you can write a new function (let's call it `getAllPlots`) that takes a list (or iterble) of datasets and plots their distributions superimposed, then call `getAllPlots([data1, data2, data3])` at the end. Would that work? – Stop harming Monica Aug 09 '19 at 10:38
  • "I can just call plt.show() at the end to get the final plot." <- that is exactly what you have to do. Matplotlib plots already do what you're asking for them to do. If you stop calling `plt.show()` inside the `getPlot` call and put `plt.show()` at the end you'll see what you want to see. – Andras Deak -- Слава Україні Aug 09 '19 at 10:48
  • 1
    @AndrasDeak If i dont call the `plt.show()` inside the function then I will lose the individual plots for each of the `data` and the end get a combination of all the plots alone at the very end. But I want both of them, the combination as well as the individual data. – a_parida Aug 09 '19 at 12:41
  • 2
    Ohhh, OK, I completely missed that. That's a bit more difficult. You still have to call `plt.show()` only at the end, but you need separate figures. The simplest solution is to create a separate figure and axes first before calling any of the functions, and passing that axes into each function, and the function both plots the data into that axes as well as into a brand new figure. I'll vote to reopen the question because then it's not a duplicate. – Andras Deak -- Слава Україні Aug 09 '19 at 12:44
  • @Goyo the problem is I don't have the data all together, I get streams of it. Also in your approach wont it be redoing everything in the `getAllPlots` which has already been done in the `getPlot` – a_parida Aug 09 '19 at 12:44
  • Seaborn needs all the data to compute the KDE so you if it can have it you can have it too. The second issue is unavoidable if you want to use `seaborn` to plot the same distribution in two places. – Stop harming Monica Aug 09 '19 at 13:25

1 Answers1

3

Since you have to keep both a separate plot and a joint one of your data you have to plot each dataset twice. Once in a separate axes and once in a common one.

What I would do is create a figure and an axes into which everything will be plotted together. Then pass that axes object into the function, and make the function plot into the axes as well as into a new figure:

def plot_twice(data, ax_all):
    # first plot into the common axes
    sns.distplot(data, hist=False, ax=ax_all)

    # and create a new figure and axes for a standalone plot
    fig,ax = plt.subplots()
    x = sns.distplot(data, hist=False, ax=ax)
    return x

# create axes for the common plot
fig,ax_all = plt.subplots()

# now plot the things
getPlot(data1, ax_all)
getPlot(data2, ax_all)
getPlot(data3, ax_all)

# only call blocking plt.show() at the end
plt.show()

It doesn't seem feasible to copy plots from one axes to the other with matplotlib (see e.g. this or this), so unless the plotting takes an excessive amount of time or memory I'd just plot the data twice for simplicity.