2016-11-27 1 views
0

Я пытаюсь сопоставить 3-ю переменную с цветом точки рассеивания в Seaborn lmplot. Итак, total_bill по x, tip по y и цвет точки как функция size.Как передать разброс kwargs на грани в lmplot в Seaborn

Он работает, если огнетушение не активировано, но не выполняется, когда используется col, потому что размер цветовой гаммы не соответствует размеру данных, нанесенных на каждый грань.

Это мой код

import matplotlib as mpl 
    import seaborn as sns 
    sns.set(color_codes=True) 

    # load data 
    data = sns.load_dataset("tips") 

    # size of data 
    print len(data.index) 

    ### we want to plot scatter point colour as function of variable 'size' 

    # first, sort the data by 'size' so that high 'size' values are plotted 
    # over the smaller sizes (so they are more visible) 

    data = data.sort_values(by=['size'], ascending=True) 

    scatter_kws = dict() 
    cmap = mpl.cm.get_cmap(name='Blues') 

    # normalise 'size' variable as float range needs to be 
    # between 0 and 1 to map to a valid colour 
    scatter_kws['c'] = data['size']/data['size'].max() 

    # map normalised values to colours 
    scatter_kws['c'] = cmap(scatter_kws['c'].values) 

    # colour array has same size as data 
    print len(scatter_kws['c']) 

    # this works as intended 
    g = sns.lmplot(data=data, x="total_bill", y="tip", scatter_kws=scatter_kws) 

Вышеприведенные хорошо работает и производит следующее (не разрешено включать в себя изображения еще, так вот ссылка):

lmplot with point colour as function of size

Однако, когда я добавьте col='sex' в lmplot (попробуйте код ниже), проблема заключается в том, что массив цветов имеет размер исходного набора данных, который больше размера данных, нанесенных на каждый грань. Так, например, col='male' имеет 157 точек данных, поэтому первые 157 значений из массива цветов отображаются в точки (и это даже не правильные). Смотрите ниже:

lmplot with point colour as function of size with col=sex

g = sns.lmplot(data=data, x="total_bill", y="tip", col="sex", scatter_kws=scatter_kws) 

В идеале, я хотел бы передать массив scatter_kws в lmplot так, что каждая грань использует правильный массив цвета (который я бы вычислить, прежде чем перейти к lmplot) , Но это не похоже на выбор.

Любые другие идеи или обходные пути, которые все еще позволяют мне использовать функциональность Сиборн в lmplot (смысл, не прибегая к Воссоздание lmplot функциональность от FacetGrid?

+0

Я не совсем понимаю, что вы пытаетесь достичь. Возможно, это помогло бы, если бы вы обновили вопрос, четко указав, какие столбцы блока данных следует использовать для какого типа визуализации. – ImportanceOfBeingErnest

+0

Отредактировано для наглядности. Спасибо :) – pistachio

+0

Я не думаю, что то, о чем вы просите, легко возможно, так как 'scatter_kws' одновременно передаются обоим диаграммам рассеяния, которые имеют (возможно) разное количество точек. Что такое функциональность от 'lmplot', которая вам нужна? – ImportanceOfBeingErnest

ответ

0

В принципе lmplot с различными cols, кажется, просто обертка для нескольких regplot с. Таким образом, вместо одного lmplot мы могли бы использовать два regplots, по одному для каждого sex.

поэтому нам нужно отделить оригинальные dataframe в male в nd female, остальное довольно прямолинейно.

import matplotlib.pyplot as plt 
import seaborn as sns 

data = sns.load_dataset("tips") 

data = data.sort_values(by=['size'], ascending=True) 
# make a new dataframe for males and females 
male = data[data["sex"] == "Male"] 
female = data[data["sex"] == "Female"] 

# get normalized colors for all data 
colors = data['size'].values/float(data['size'].max()) 
# get colors for males/females 
colors_male = colors[data["sex"].values == "Male"] 
colors_female = colors[data["sex"].values == "Female"] 
# colors are values in [0,1] range 


fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(9,4)) 

#create regplot for males, put it to left axes 
#use colors_male to color the points with Blues cmap 
sns.regplot(data=male, x="total_bill", y="tip", ax=ax1, 
      scatter_kws= {"c" : colors_male, "cmap":"Blues"}) 
# same for females 
sns.regplot(data=female, x="total_bill", y="tip", ax=ax2, 
      scatter_kws={"c" : colors_female, "cmap":"Greens"}) 
ax1.set_title("Males") 
ax2.set_title("Females") 
for ax in [ax1, ax2]: 
    ax.set_xlim([0,60]) 
    ax.set_ylim([0,12]) 
plt.tight_layout() 
plt.show() 

enter image description here

+0

Спасибо. Это не произошло со мной, и это действительно хороший способ обхода – pistachio

Смежные вопросы