Seaborn/Matplotlib:如何在FacetGrid中访问线条值?

8
我正在尝试在Seaborn FacetGrid中给两条线之间着色。 fill_between 方法可以实现这一目的,但是我需要访问每个子图中每条线的值以将其传递给该方法。
以下是我的代码:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

data = [{'Change': 0.0,  'Language': 'Algonquin',  'Type': 'Mother tongue',  'Year': '2011'}, {'Change': 0.0,  'Language': 'Algonquin',  'Type': 'Spoken at home',  'Year': '2011'}, {'Change': -21.32,  'Language': 'Algonquin',  'Type': 'Mother tongue',  'Year': '2016'}, {'Change': -34.84,  'Language': 'Algonquin',  'Type': 'Spoken at home',  'Year': '2016'}, {'Change': 0.0,  'Language': 'Atikamekw',  'Type': 'Mother tongue',  'Year': '2011'}, {'Change': 0.0,  'Language': 'Atikamekw',  'Type': 'Spoken at home',  'Year': '2011'}, {'Change': 5.41,  'Language': 'Atikamekw',  'Type': 'Mother tongue',  'Year': '2016'}, {'Change': 19.15,  'Language': 'Atikamekw',  'Type': 'Spoken at home',  'Year': '2016'}, {'Change': 0.0,  'Language': 'Blackfoot',  'Type': 'Mother tongue',  'Year': '2011'}, {'Change': 0.0,  'Language': 'Blackfoot',  'Type': 'Spoken at home',  'Year': '2011'}, {'Change': -1.4,  'Language': 'Blackfoot',  'Type': 'Mother tongue',  'Year': '2016'}, {'Change': 61.42,  'Language': 'Blackfoot',  'Type': 'Spoken at home',  'Year': '2016'}, {'Change': 0.0,  'Language': 'Carrier',  'Type': 'Mother tongue',  'Year': '2011'}, {'Change': 0.0,  'Language': 'Carrier',  'Type': 'Spoken at home',  'Year': '2011'}, {'Change': -20.38,  'Language': 'Carrier',  'Type': 'Mother tongue',  'Year': '2016'}, {'Change': -18.91,  'Language': 'Carrier',  'Type': 'Spoken at home',  'Year': '2016'}, {'Change': 0.0,  'Language': 'Chilcotin',  'Type': 'Mother tongue',  'Year': '2011'}, {'Change': 0.0,  'Language': 'Chilcotin',  'Type': 'Spoken at home',  'Year': '2011'}, {'Change': -13.82,  'Language': 'Chilcotin',  'Type': 'Mother tongue',  'Year': '2016'}, {'Change': 7.41,  'Language': 'Chilcotin',  'Type': 'Spoken at home',  'Year': '2016'}, {'Change': 0.0,  'Language': 'Cree languages',  'Type': 'Mother tongue',  'Year': '2011'}, {'Change': 0.0,  'Language': 'Cree languages',  'Type': 'Spoken at home',  'Year': '2011'}, {'Change': -11.52,  'Language': 'Cree languages',  'Type': 'Mother tongue',  'Year': '2016'}, {'Change': 6.57,  'Language': 'Cree languages',  'Type': 'Spoken at home',  'Year': '2016'}]

langs = pd.DataFrame(data)
g = sns.FacetGrid(langs, col='Language', hue='Type', col_wrap = 4, size=2)
g.map(plt.plot, 'Year', 'Change').set_titles('{col_name}')
g.set(xticks=[2011, 2016], yticks = [-40, 0, 70] )

这将导致生成以下图表: enter image description here 现在我如何访问每条线的值?我猜应该是使用g.axes,但文档中没有相关信息。
2个回答

10

通过 ax.lines 获取FacetGrid的扁平坐标轴数组,然后迭代这些线条并使用 get_xdata, get_ydata 方法获取线条的数据,随后可以根据这些数据进行需要的操作。

示例代码:

...
for ax in g.axes.flat:
    print (ax.lines)
    for line in ax.lines:
        print (line.get_xdata())
        print (line.get_ydata())

您的代码输出数据如下:
[<matplotlib.lines.Line2D object at 0x10c5facc0>, <matplotlib.lines.Line2D object at 0x10c5fa940>]
['2011' '2016']
[  0.   -21.32]
['2011' '2016']
[  0.   -34.84]
[<matplotlib.lines.Line2D object at 0x10c39a160>, <matplotlib.lines.Line2D object at 0x10c5a4828>]
['2011' '2016']
[ 0.    5.41]
['2011' '2016']
[  0.    19.15]
[<matplotlib.lines.Line2D object at 0x10c5ff6d8>, <matplotlib.lines.Line2D object at 0x10c67c630>]
['2011' '2016']
[ 0.  -1.4]
['2011' '2016']
[  0.    61.42]
[<matplotlib.lines.Line2D object at 0x10c637358>, <matplotlib.lines.Line2D object at 0x10c65ada0>]
['2011' '2016']
[  0.   -20.38]
['2011' '2016']
[  0.   -18.91]
[<matplotlib.lines.Line2D object at 0x10c613668>, <matplotlib.lines.Line2D object at 0x10c6134e0>]
['2011' '2016']
[  0.   -13.82]
['2011' '2016']
[ 0.    7.41]
[<matplotlib.lines.Line2D object at 0x10c5ffd30>, <matplotlib.lines.Line2D object at 0x10c4f5dd8>]
['2011' '2016']
[  0.   -11.52]
['2011' '2016']
[ 0.    6.57]

这非常方便,谢谢。在等待答案的同时,我还发现可以通过每个轴中的 get_children()get_data() 访问数据值,但是您的解决方案更加简洁。 - robroc

3

延伸自@Serenity's的回答。使用线信息get_xdata, get_ydata,您可以像下面这样使用fill_between

g = sns.FacetGrid(langs, col='Language', hue='Type', col_wrap=4, size=3)
g.map(plt.plot, 'Year', 'Change').set_titles('{col_name}')
g.set(xticks=[2011, 2016], yticks = [-40, 0, 70] )
for ax in g.axes.flat:
    ax.fill_between(ax.lines[0].get_xdata().astype(int),
                    ax.lines[0].get_ydata(0), ax.lines[1].get_ydata(),
                    facecolor='#ffdec1')

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接