I have a problem in a Qt application when I attempt to plot my dataframe as an area plot with a time index using pandas plotting function in combination with Seaborn's FacetGrids. What happens is that a grid layout is correctly created, but the plots do not appear in these grids. Using a Seaborn plotting function works as expected, though.
I tried to figure out what's going on by isolating the drawing routines from the rest of my code, and I've found a rather unexpected behaviour as shown below (using ipython notebook):
%matplotlib inline
import pandas as pd
import seaborn as sns
df = pd.DataFrame({
"Home": [76, 64, 38, 78, 63, 45, 32, 46, 13, 40],
"Away": [55, 67, 70, 56, 59, 69, 72, 24, 45, 21],
"Team": ["T1"] * 5 + ["T2"] * 5,
"Year": ["1991", "1992", "1993", "1994", "1995"] * 2})
Now, what I want to do is to draw two facets, one for each team. Each facet should show the 'Away' and 'Home' columns as two separate time series. In line with the suggestion in another question (Plotting time series using Seaborn FacetGrid), I wrote a function that calls the pandas plotting function for the subset passed to it by map_dataframe():
def plot_area(data, color):
data[["Home", "Away"]].index = pd.to_datetime(data["Year"])
data[["Home", "Away"]].plot(kind="area")
However, when using this function, the result is rather unexpected: the FacetGrid is created and initialized correctly, but the two calls to the pandas method do not use this grid as their plotting region, and they appear elsewhere.
g = sns.FacetGrid(df, col="Team")
g.map_dataframe(plot_area)
<seaborn.axisgrid.FacetGrid at 0x1a25110>
Screenshot of output:
In the post I linked above, @mwaskom notes that methods called in this way
must draw a plot on the "currently active" matplotlib Axes.
Perhaps that is the problem here? The code as such appears to be correct, because with a different plotting function, everything works as expected, e.g. with a sns.heatmap():
def plot_heatmap(data, color):
sns.heatmap(data[["Home", "Away"]])
g = sns.FacetGrid(df, col="Team")
g.map_dataframe(plot_heatmap)
<seaborn.axisgrid.FacetGrid at 0x4a6d110>
Screenshot of output:
So, my question boils down to this: how do I have to change the function plot_area() so that the axes produced by the pandas plotting function appear on the subplots created by Seaborn's FacetGrid?
(pandas version 0.16.0, Seaborn version 0.6.0, ipython 3.2.1, Python 2.7)
The comment by mwaskom set me on the right track: I have to provide the current axes to the plot function (now this seems so obvious...). For future reference, this is a working solution to my problem:
def plot_area(data, color):
data.index = pd.to_datetime(data["Year"])
data[["Home", "Away"]].plot(kind="area", ax=plt.gca())
g = sns.FacetGrid(df, col="Team")
g.map_dataframe(plot_area)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With