簡體   English   中英

在 xy 散點圖中添加標簽 plot 和 seaborn

[英]Adding labels in x y scatter plot with seaborn

我花了幾個小時嘗試完成我認為是一項簡單的任務,即在使用 seaborn 的同時將標簽添加到 XY plot 上。

這是我的代碼

import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline

df_iris=sns.load_dataset("iris") 

sns.lmplot('sepal_length', # Horizontal axis
           'sepal_width', # Vertical axis
           data=df_iris, # Data source
           fit_reg=False, # Don't fix a regression line
           size = 8,
           aspect =2 ) # size and dimension

plt.title('Example Plot')
# Set x-axis label
plt.xlabel('Sepal Length')
# Set y-axis label
plt.ylabel('Sepal Width')

我想在 plot 的每個點上添加“物種”列中的文本。

我見過很多使用 matplotlib 但不使用 seaborn 的示例。

有任何想法嗎? 謝謝你。

您可以這樣做的一種方法如下:

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline

df_iris=sns.load_dataset("iris") 

ax = sns.lmplot('sepal_length', # Horizontal axis
           'sepal_width', # Vertical axis
           data=df_iris, # Data source
           fit_reg=False, # Don't fix a regression line
           size = 10,
           aspect =2 ) # size and dimension

plt.title('Example Plot')
# Set x-axis label
plt.xlabel('Sepal Length')
# Set y-axis label
plt.ylabel('Sepal Width')


def label_point(x, y, val, ax):
    a = pd.concat({'x': x, 'y': y, 'val': val}, axis=1)
    for i, point in a.iterrows():
        ax.text(point['x']+.02, point['y'], str(point['val']))

label_point(df_iris.sepal_length, df_iris.sepal_width, df_iris.species, plt.gca())  

在此處輸入圖片說明

這是一個更新的答案,不受評論中描述的字符串問題的影響。

import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline

df_iris=sns.load_dataset("iris") 

plt.figure(figsize=(20,10))
p1 = sns.scatterplot('sepal_length', # Horizontal axis
       'sepal_width', # Vertical axis
       data=df_iris, # Data source
       size = 8,
       legend=False)  

for line in range(0,df_iris.shape[0]):
     p1.text(df_iris.sepal_length[line]+0.01, df_iris.sepal_width[line], 
     df_iris.species[line], horizontalalignment='left', 
     size='medium', color='black', weight='semibold')

plt.title('Example Plot')
# Set x-axis label
plt.xlabel('Sepal Length')
# Set y-axis label
plt.ylabel('Sepal Width')

在此處輸入圖片說明

感謝其他 2 個答案,這里有一個函數scatter_text可以多次重用這些圖。

import seaborn as sns
import matplotlib.pyplot as plt

def scatter_text(x, y, text_column, data, title, xlabel, ylabel):
    """Scatter plot with country codes on the x y coordinates
       Based on this answer: https://stackoverflow.com/a/54789170/2641825"""
    # Create the scatter plot
    p1 = sns.scatterplot(x, y, data=data, size = 8, legend=False)
    # Add text besides each point
    for line in range(0,data.shape[0]):
         p1.text(data[x][line]+0.01, data[y][line], 
                 data[text_column][line], horizontalalignment='left', 
                 size='medium', color='black', weight='semibold')
    # Set title and axis labels
    plt.title(title)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    return p1

使用該函數如下:

df_iris=sns.load_dataset("iris") 
plt.figure(figsize=(20,10))
scatter_text('sepal_length', 'sepal_width', 'species',
             data = df_iris, 
             title = 'Iris sepals', 
             xlabel = 'Sepal Length (cm)',
             ylabel = 'Sepal Width (cm)')

另請參閱有關如何使用返回繪圖的函數的答案: https : //stackoverflow.com/a/43926055/2641825

下面是一個不使用可怕的 for 循環迭代數據框中的行的解決方案。

關於遍歷數據框有很多問題。

答案是不要迭代! 請參閱此鏈接

下面的解決方案依賴於 petalplot function 中的petalplot ( plotlabel ),它由df.apply

現在,我知道讀者會對我使用scatter而不是lmplot的事實發表評論,但這有點離題了。

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline

df_iris=sns.load_dataset("iris") 

def petalplot(df): 
    
    def plotlabel(xvar, yvar, label):
        ax.text(xvar+0.002, yvar, label)
        
    fig = plt.figure(figsize=(30,10))
    ax = sns.scatterplot(x = 'sepal_length', y = 'sepal_width', data=df)

    # The magic starts here:
    df.apply(lambda x: plotlabel(x['sepal_length'],  x['sepal_width'], x['species']), axis=1)

    plt.title('Example Plot')
    plt.xlabel('Sepal Length')
    plt.ylabel('Sepal Width')
    
petalplot(df_iris)

Scott Boston's answer 的想法相同,但是對於 Seaborn v0.12+,您可以利用seaborn.FacetGrid.apply在繪圖上添加標簽並在一個 go 中設置您的圖形:

import seaborn as sns
import pandas as pd

%matplotlib inline

sns.set_theme()

df_iris = sns.load_dataset("iris")
(
    sns.lmplot(
        data=df_iris,
        x="sepal_length",
        y="sepal_width",
        fit_reg=False,
        height=8,
        aspect=2
    )
    .apply(lambda grid: [
        grid.ax.text(r["sepal_length"]+.02, r["sepal_width"], r["species"])
        for r in df_iris.to_dict(orient="records")
    ])
    .set(title="Example Plot")
    .set_axis_labels("Sepal Length", "Sepal Width")
)

或者,如果您不需要使用lmplot ,同樣從 v0.12 開始,您可以使用seaborn.objects 接口 這樣我們就不需要手動迭代 Iris dataframe 也不需要多次引用df_iris或列名sepal_... _...。

import seaborn.objects as so
(
    so.Plot(df_iris, x="sepal_length", y="sepal_width", text="species")
        .add(so.Dot())
        .add(so.Text(halign="left"))
        .label(title="Example plot", x="Sepal Length", y="Sepal Width")
        .layout(size=(20, 10))
)

這會產生下圖:

在此處輸入圖像描述

使用強大的聲明 API來避免循環 ( seaborn>=0.12 )。

具體來說,將 x、y 和注釋放入 pandas 數據框中並調用繪圖。

這是我自己的研究工作中的一個例子。

import seaborn.objects as so
import pandas as pd

df = pd.DataFrame(..,columns=['phase','P(X=1)','text'])

fig,ax = plt.subplots()
    p = so.Plot(df,x='phase',y='P(X=1)',text='text').add(so.Dot(marker='+')).add(so.Text(halign='left'))
    p.on(ax).show()

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM