Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Visualizer does not forget previous plot. #579

Closed
zjpoh opened this issue Aug 22, 2018 · 1 comment
Closed

Visualizer does not forget previous plot. #579

zjpoh opened this issue Aug 22, 2018 · 1 comment
Labels
type: bug something isn't working

Comments

@zjpoh
Copy link
Contributor

zjpoh commented Aug 22, 2018

Describe the bug
When making consecutive plots in python script, the older plots are still visible.

To Reproduce
In doc/api/target/,

python class_balance.py

Expected behavior
class_balance_compare
class_balance

Traceback
class_balance_compare
class_balance

The second plot contains the first plot.

This can be solved by adding plt.gcf().clear() after viz.poof().

Desktop (please complete the following information):

  • OS: macOS & Ubuntu
  • Python Version 3.6
  • Yellowbrick Version dev
@bbengfort bbengfort added ready type: bug something isn't working labels Aug 22, 2018
@bbengfort
Copy link
Member

@zjpoh thanks for bringing this to our attention, and you're right this certainly can be a problem. Unfortunately, there isn't as easy a solution as there seems at first glance.

Matplotlib has two primary "global" drawing concepts - the figure and the axes. The figure holds one or more axes and is what is rendered, sized, and manipulated with event handlers. The axes is the canvas that we draw artists on. Most individual visualizers are drawn on only a single axes object, and similar to the pandas and seaborn APIs, they take an axes object that they can draw on. By default, ax=None and so to get the axes, the visualizer calls plt.gca -- get current axes; and that's what's causing what you're observing above.

This means that the primary way we resolve this issue is as follows:

import matplotlib.pyplot as plt 

# First figure 
fig, ax = plt.subplots(figsize=(9,6)) 
viz = Visualizer(ax=ax) 
viz.fit_transform(X, y) 
viz.poof() 

# Second figure 
fig2, ax2 = plt.subplots(figsize=(9,6)) 
viz2 = Visualizer(ax=ax2) 
... 

The primary way we do this is so that we can compose multiple visualizers as a single figure, e.g. the GridVisualizer and FlipBookVisualizer. Very often in my code you'll see:

fig, axes = plt.subplots(cols=2, figsize=(18, 6)) 
viza = Visualizer(ax=axes[0]) 
vizb = Visualizer(ax=axes[1]) 

As a result, we've been very careful not to do anything with the figure in Yellowbrick code, jumping through a lot of hoops in the ResidualsPlot, JointPlot, and InterclusterDistance visualizers to ensure that we're only drawing on the axes specified ...

See related issues #176, #380, #375, #158, #168, #62

That doesn't mean that we don't need to solve this problem -- the question is how. I'll comment on clearing the figure in the PR you opened, which by the way - thanks! I really appreciate that you opened the issue and submitted a PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants