pandas Seaborn FacetGrid 上的绘图
pandas plots on Seaborn FacetGrid
当我尝试结合使用 pandas 绘图函数和 Seaborn 的 FacetGrids 将我的数据框绘制为具有时间索引的区域图时,我在 Qt 应用程序中遇到了问题。发生的情况是正确创建了网格布局,但这些网格中没有出现绘图。不过,使用 Seaborn 绘图函数可以按预期工作。
我试图通过将绘图例程与我的其余代码隔离开来弄清楚发生了什么,我发现了一个非常出乎意料的行为,如下所示(使用 ipython 笔记本):
%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})
现在,我要做的是绘制两个方面,每个团队一个。每个构面应将 'Away' 和 'Home' 列显示为两个单独的时间序列。根据另一个问题(Plotting time series using Seaborn FacetGrid)中的建议,我编写了一个函数,该函数调用 map_dataframe():
传递给它的子集的 pandas 绘图函数
def plot_area(data, color):
data[["Home", "Away"]].index = pd.to_datetime(data["Year"])
data[["Home", "Away"]].plot(kind="area")
然而,当使用这个函数时,结果是相当出乎意料的:FacetGrid 被正确创建和初始化,但是对 pandas 方法的两次调用并没有使用这个网格作为它们的绘图区域,并且它们出现在别处。
g = sns.FacetGrid(df, col="Team")
g.map_dataframe(plot_area)
<seaborn.axisgrid.FacetGrid at 0x1a25110>
输出截图:
在我上面链接的 post 中,@mwaskom 指出以这种方式调用的方法
must draw a plot on the "currently active" matplotlib Axes.
也许这就是问题所在?这样的代码似乎是正确的,因为使用不同的绘图功能,一切都按预期工作,例如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>
输出截图:
所以,我的问题归结为:我如何更改函数 plot_area() 以便 pandas 绘图函数生成的轴出现在 Seaborn 创建的子图中FacetGrid?
(pandas 版本 0.16.0, Seaborn 版本 0.6.0, ipython 3.2.1, Python 2.7)
mwaskom 的评论让我走上了正确的轨道:我必须为绘图函数提供当前轴(现在这看起来很明显......)。为了将来参考,这是我的问题的有效解决方案:
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)
当我尝试结合使用 pandas 绘图函数和 Seaborn 的 FacetGrids 将我的数据框绘制为具有时间索引的区域图时,我在 Qt 应用程序中遇到了问题。发生的情况是正确创建了网格布局,但这些网格中没有出现绘图。不过,使用 Seaborn 绘图函数可以按预期工作。
我试图通过将绘图例程与我的其余代码隔离开来弄清楚发生了什么,我发现了一个非常出乎意料的行为,如下所示(使用 ipython 笔记本):
%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})
现在,我要做的是绘制两个方面,每个团队一个。每个构面应将 'Away' 和 'Home' 列显示为两个单独的时间序列。根据另一个问题(Plotting time series using Seaborn FacetGrid)中的建议,我编写了一个函数,该函数调用 map_dataframe():
传递给它的子集的 pandas 绘图函数def plot_area(data, color):
data[["Home", "Away"]].index = pd.to_datetime(data["Year"])
data[["Home", "Away"]].plot(kind="area")
然而,当使用这个函数时,结果是相当出乎意料的:FacetGrid 被正确创建和初始化,但是对 pandas 方法的两次调用并没有使用这个网格作为它们的绘图区域,并且它们出现在别处。
g = sns.FacetGrid(df, col="Team")
g.map_dataframe(plot_area)
<seaborn.axisgrid.FacetGrid at 0x1a25110>
输出截图:
在我上面链接的 post 中,@mwaskom 指出以这种方式调用的方法
must draw a plot on the "currently active" matplotlib Axes.
也许这就是问题所在?这样的代码似乎是正确的,因为使用不同的绘图功能,一切都按预期工作,例如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>
输出截图:
所以,我的问题归结为:我如何更改函数 plot_area() 以便 pandas 绘图函数生成的轴出现在 Seaborn 创建的子图中FacetGrid?
(pandas 版本 0.16.0, Seaborn 版本 0.6.0, ipython 3.2.1, Python 2.7)
mwaskom 的评论让我走上了正确的轨道:我必须为绘图函数提供当前轴(现在这看起来很明显......)。为了将来参考,这是我的问题的有效解决方案:
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)