matplotlib 为自定义海运贴图函数填充凸包中的面颜色

4dc9hkyq  于 2023-02-05  发布在  其他
关注(0)|答案(1)|浏览(166)

我尝试使用Matplotlib将着色的凸包覆盖到散点图seaborn.relplot中的不同组。基于question和Seaborn示例,我已经能够成功地覆盖企鹅数据集中每个sex的凸包。

# Import libraries
import pandas as pd
import numpy as np

from scipy.spatial import ConvexHull
import matplotlib.pyplot as plt
import seaborn as sns

sns.set_style('whitegrid')

data = sns.load_dataset("penguins")
xcol = 'bill_length_mm'
ycol = 'bill_depth_mm'

g = sns.relplot(data = data, x=xcol, y = ycol,
                hue = "sex", style = "sex",
                col = 'species', palette="Paired",
                kind = 'scatter')

def overlay_cv_hull_dataframe(x, y, color, **kwargs):

    data = kwargs.pop('data')
    # Get the Convex Hull for each group based on hue
    for _, group in data.groupby('hue'):
        points = group[['x', 'y']].values
        hull = ConvexHull(points)
        for simplex in hull.simplices:
            plt.fill(points[simplex, 0], points[simplex, 1], 
                    facecolor = color, alpha=0.5, 
                    edgecolor = color)

# Overlay convex hulls
g.map_dataframe(overlay_cv_hull_dataframe, x=xcol, y=ycol,
                hue='sex')
g.set_axis_labels(xcol, ycol)

但是,凸包填充的颜色与边的颜色不同,尽管我已指定

plt.fill(points[simplex, 0], points[simplex, 1], 
                    facecolor = color, alpha=0.5,
                    edgecolor = color, # color is an RGB tuple like (0.12, 0.46, 0.71)
                    )

我也试过像这个例子一样设置facecolor='lightsalmon'并删除alpha参数,但得到的是相同的图。我想我真的很接近了,但我不确定还能尝试什么。
我怎样才能让凸包填充与edgecolor相同的color和点?

czq61nw1

czq61nw11#

(Your代码似乎有一些打字错误,写'x''y''hue'而不是xyhue)。
simplex包含船体的 * 一 * 条边的坐标索引。要填充多边形,需要所有边,或hull.vertices
g.map_dataframe在每个子图中只调用一次函数。因此,color仅在不使用hue时可用。相反,您需要将各个颜色存储在调色板字典中。在plt.fill中,alpha同时应用于面颜色和边颜色。您可以使用to_rgba为面颜色给予透明,同时使用不带alpha的边颜色。

import pandas as pd
import numpy as np
from scipy.spatial import ConvexHull
import matplotlib.pyplot as plt
from matplotlib.colors import to_rgba
import seaborn as sns

sns.set_style('whitegrid')

data = sns.load_dataset("penguins")
xcol = 'bill_length_mm'
ycol = 'bill_depth_mm'

hues = data["sex"].unique()
colors = sns.color_palette("Paired", len(hues))
palette = {hue_val: color for hue_val, color in zip(hues, colors)}
g = sns.relplot(data=data, x=xcol, y=ycol, hue="sex", style="sex", col='species', palette=palette, kind='scatter')

def overlay_cv_hull_dataframe(x, y, color, data, hue):
    # Get the Convex Hull for each group based on hue
    for hue_val, group in data.groupby(hue):
        hue_color = palette[hue_val]
        points = group[[x, y]].values
        hull = ConvexHull(points)
        plt.fill(points[hull.vertices, 0], points[hull.vertices, 1],
                 facecolor=to_rgba(hue_color, 0.2),
                 edgecolor=hue_color)

# Overlay convex hulls
g.map_dataframe(overlay_cv_hull_dataframe, x=xcol, y=ycol, hue='sex')
g.set_axis_labels(xcol, ycol)

plt.show()

相关问题