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

Colorbar in FacetGrid #582

Closed
demianw opened this issue Jun 5, 2015 · 9 comments
Closed

Colorbar in FacetGrid #582

demianw opened this issue Jun 5, 2015 · 9 comments
Labels

Comments

@demianw
Copy link

demianw commented Jun 5, 2015

Hi! I've used the great FacetGrid class to plot a series of 2D plots (e.g. contourf).
However, I have not found a way to activate the colorbars such as those existing in matplotlib's AxesGrid toolkit (http://matplotlib.org/mpl_toolkits/axes_grid/users/overview.html).

Is there a way to do this that I'm missing, do you have a recommendation?

Thanks!

@mwaskom
Copy link
Owner

mwaskom commented Jun 5, 2015

Can you show an example of how you're using FacetGird for this? It's not straightforward to begin with so that would be helpful.

@demianw
Copy link
Author

demianw commented Jun 6, 2015

Here you have an example. I could probably do a pull request to add a map_ method that extends the FacetGrid functionality (I will let you pick the right to put in)

import numpy as np
import pandas
import seaborn as sns

x, y = np.meshgrid(np.linspace(0, 100), np.linspace(0, 100))

df = pandas.DataFrame(dict(
       x=r_[x.ravel(), x.ravel()],
       y=r_[y.ravel(), y.ravel()],
       s=r_[
           np.ones_like(x.ravel()),
           np.ones_like(x.ravel()) * 10
       ]
))

df['value'] = (
   df.x *
   exp(-((df.x - df.y) ** 2 / df.s ** 2))
)

g = sns.FacetGrid(df, col='s')

def data_frame_to_matrix(fn):
   def dummy(*args, **kwargs):
       data_ = kwargs['data']
       kwargs_ = kwargs.copy()
       del kwargs_['data']
       del kwargs_['color']
       data_ = data_.pivot(args[1], args[0])[args[2]]
       X, Y = meshgrid(data_.columns, data_.index)
       return fn(X, Y, data_, *args[3:], **kwargs_)
   return dummy

g.map_dataframe(
   data_frame_to_matrix(contourf),
   'x', 'y', 'value', 5,
)

@mwaskom
Copy link
Owner

mwaskom commented Jun 12, 2015

Interestingly, just putting plt.colorbar at the end of your code actually does a nice job: (I also added vmin and vmax in map to ensure that the colorbar limits are valid for all facets):

a18oxuceaoutaaaaaelftksuqmcc

Though I doubt this will generally work for all functions that could use a colorbar.

I wonder why fig._gci() is a private method; that's what plt.colorbar is using to find the most sensible thing to draw a colorbar for, and it would be useful for seaborn to take advantage of, but it's private.

@mwaskom
Copy link
Owner

mwaskom commented Jun 12, 2015

See also matplotlib/matplotlib#4517

@mwaskom
Copy link
Owner

mwaskom commented Jun 12, 2015

Unfortunately I've gotten a completely unhelpful response from matplotlib core (no surprise there) so it doesn't look like this is going to go anywhere...

@demianw
Copy link
Author

demianw commented Jun 12, 2015

Thanks! What I wanted was one colorbar per grid plot that's why the plt.colorbar was not a feasible solution. Sorry if I didn't express this well. Probably mimicking some of the work on matplotlib axesgrid. But I don't know how compatible this is with your gridding method and it might be better strategy to wrap their axesgrid with some code that generates the grid using data frame info

Demian Wassermann, PhD
demian.wassermann@inria.fr
Research Scientist
Athena Project Team
INRIA Sophia Antipolis - Méditerranée
2004 route des lucioles - FR-06902

On Jun 12, 2015, at 17:58, Michael Waskom notifications@github.com wrote:

Unfortunately I've gotten a completely unhelpful response from matplotlib core (no surprise there) so it doesn't look like this is going to go anywhere...


Reply to this email directly or view it on GitHub.

@mwaskom
Copy link
Owner

mwaskom commented Jun 12, 2015

Oh, that's actually somewhat easier. Here's what I would do:

g = sns.FacetGrid(df, col='s')

def contourplot(*args, **kwargs):

    data = kwargs.pop("data").pivot(args[1], args[0])[args[2]]
    X, Y = np.meshgrid(data.columns, data.index)
    ax = plt.gca()
    mappable = ax.contourf(X, Y, data, *args[3:], **kwargs)
    ax.figure.colorbar(mappable)

g.map_dataframe(contourplot, 'x', 'y', 'value', 5)

znwmegosjcaaaaaelftksuqmcc

@demianw
Copy link
Author

demianw commented Jun 12, 2015

Great! It was the ax.figure bit that I was missing! Thanks

Demian Wassermann, PhD
demian.wassermann@inria.fr
Research Scientist
Athena Project Team
INRIA Sophia Antipolis - Méditerranée
2004 route des lucioles - FR-06902

On Jun 12, 2015, at 18:28, Michael Waskom notifications@github.com wrote:

Oh, that's actually somewhat easier. Here's what I would do:

g = sns.FacetGrid(df, col='s')

def contourplot(_args, *_kwargs):

data = kwargs.pop("data").pivot(args[1], args[0])[args[2]]
X, Y = np.meshgrid(data.columns, data.index)
ax = plt.gca()
mappable = ax.contourf(X, Y, data, *args[3:], **kwargs)
ax.figure.colorbar(mappable)

g.map_dataframe(contourplot, 'x', 'y', 'value', 5)


Reply to this email directly or view it on GitHub.

@mwaskom
Copy link
Owner

mwaskom commented Jun 12, 2015

Glad it works!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants