【问题标题】:FacetGrid with contour plots带有等高线图的 FacetGrid
【发布时间】:2021-11-05 21:22:13
【问题描述】:

为了找到支持向量回归的最佳超参数,我使用 DataFrame 进行了网格搜索,结果如下:

svr__kernel svr__C  svr__epsilon   mae  
rbf         0.01    0.1            19.80    
linear      0.01    0.1            19.00    
poly2       0.01    0.1            19.72    
rbf         0.01    0.2            19.76
..          ..      ..             ..

为了可视化结果,我为一个内核创建了等高线图。

fig, ax = plt.subplots(figsize=(15,7))

plot_df = df[df.svr__kernel == "poly2"].copy()
C = plot_df["svr__C"]
epsilon = plot_df["svr__epsilon"]
score = plot_df["mae"]

# Plotting all evaluations:
ax.plot(C, epsilon, "ko", ms=1)
# Create a contour plot
cntr = ax.tricontourf(C, epsilon, score, levels=12, cmap="RdBu_r")
# Adjusting the colorbar
fig.colorbar(cntr, ax=ax, label="MAE")
# Adjusting the axis limits
ax.set(
    xlim=(min(C), max(C)),
    ylim=(min(epsilon), max(epsilon)),
    xlabel="C",
    ylabel="Epsilon",
)
ax.set_title("SVR performance landscape")

现在我想要一个 FacetGrid,其中包含来自每个内核的等高线图,以及 mae 值的相同颜色条。不幸的是,我在理解 FacetGrids 的过程中遇到了严重的问题。

【问题讨论】:

    标签: python pandas dataframe matplotlib seaborn


    【解决方案1】:

    回答

    如果你有这样的数据框:

    kernels = ['rbf', 'linear', 'poly2']
    c_size = 10
    eps_size = 10
    df = pd.DataFrame({'svr__kernel': np.repeat(kernels, c_size*eps_size),
                       'svr__C': len(kernels)*eps_size*list(np.linspace(0, 5, c_size)),
                       'svr__epsilon': len(kernels)*list(np.repeat(np.linspace(0.1, 1, eps_size), c_size))})
    df['mae'] = 15 + 10*np.random.random(len(df))
    
        svr__kernel    svr__C  svr__epsilon        mae
    0           rbf  0.000000           0.1  18.745401
    1           rbf  0.555556           0.1  24.507143
    2           rbf  1.111111           0.1  22.319939
    3           rbf  1.666667           0.1  20.986585
    4           rbf  2.222222           0.1  16.560186
    ..          ...       ...           ...        ...
    295       poly2  2.777778           1.0  20.222433
    296       poly2  3.333333           1.0  22.699936
    297       poly2  3.888889           1.0  17.158210
    298       poly2  4.444444           1.0  21.228905
    299       poly2  5.000000           1.0  15.853475
    

    您可以通过以下方式设置seaborn.FacetGrid

    overall_min = df['mae'].min()
    overall_max = df['mae'].max()
    cmap = RdBu_r
    levels = 12
    
    g = sns.FacetGrid(df, col = 'svr__kernel')
    g.map(plt.tricontourf, 'svr__C', 'svr__epsilon', 'mae', levels = levels, cmap = cmap, vmin = overall_min, vmax = overall_max)
    

    然后您可以将最后一个图移到左侧,以便为颜色条腾出一些空间,添加一个轴并在其上绘制颜色图:

    g.fig.subplots_adjust(right = 0.88)
    cbar_ax = g.fig.add_axes([0.9, 0.1, 0.03, 0.8])
    norm = BoundaryNorm(np.linspace(overall_min, overall_max, levels), cmap.N)
    plt.colorbar(ScalarMappable(norm = norm, cmap = cmap), cax = cbar_ax)
    

    完整代码

    在此示例中,我将 3 添加到 'mae' 列,其中 add_3_to_poly2 函数仅适用于 'poly2' 内核,目的是检查与轮廓级别相关的颜色条值。

    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    import numpy as np
    from matplotlib.cm import ScalarMappable, RdBu_r
    from matplotlib.colors import BoundaryNorm
    
    
    def add_3_to_poly2(df):
        if df['svr__kernel'] == 'poly2':
            return df['mae'] + 3
        else:
            return df['mae']
    
    
    kernels = ['rbf', 'linear', 'poly2']
    c_size = 10
    eps_size = 10
    df = pd.DataFrame({'svr__kernel': np.repeat(kernels, c_size*eps_size),
                       'svr__C': len(kernels)*eps_size*list(np.linspace(0, 5, c_size)),
                       'svr__epsilon': len(kernels)*list(np.repeat(np.linspace(0.1, 1, eps_size), c_size))})
    df['mae'] = 15 + 10*np.random.random(len(df))
    df['mae'] = df.apply(add_3_to_poly2, axis = 1)
    
    
    overall_min = df['mae'].min()
    overall_max = df['mae'].max()
    cmap = RdBu_r
    levels = 12
    
    g = sns.FacetGrid(df, col = 'svr__kernel')
    g.map(plt.tricontourf, 'svr__C', 'svr__epsilon', 'mae', levels = levels, cmap = cmap, vmin = overall_min, vmax = overall_max)
    
    g.fig.subplots_adjust(right = 0.88)
    cbar_ax = g.fig.add_axes([0.9, 0.1, 0.03, 0.8])
    norm = BoundaryNorm(np.linspace(overall_min, overall_max, levels), cmap.N)
    plt.colorbar(ScalarMappable(norm = norm, cmap = cmap), cax = cbar_ax)
    
    plt.show()
    

    情节

    注意事项

    如您所见,'poly2' contourf 值实际上大于其他值,并且颜色条正确跟踪所有值,从总体最小值到总体最大值。

    【讨论】:

      猜你喜欢
      • 2019-09-22
      • 1970-01-01
      • 2019-08-01
      • 2018-10-05
      • 1970-01-01
      • 2019-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多