2015-03-25 4 views
5

Dziwne zachowanie podczas używania pand i seaborn do wykreślenia wykresu punktowego, który ma tylko trzy punkty: punkty nie mają tego samego koloru. Problem znika, gdy seaborn nie jest załadowany lub gdy jest więcej niż trzy punkty, lub gdy kreślona jest bezpośrednio metodą punktową matplotlib. Zobacz poniższy przykład:pandy rozpraszają kolory z trzema punktami i seabornem

from pandas import DataFrame #0.16.0 
import matplotlib.pyplot as plt #1.4.3 
import seaborn as sns #0.5.1 
import numpy as np #1.9.2 

df = DataFrame({'x': np.random.uniform(0, 1, 3), 'y': np.random.uniform(0, 1, 3)}) 
df.plot(kind = 'scatter', x = 'x', y = 'y') 
plt.show() 

df = DataFrame({'x': np.random.uniform(0, 1, 4), 'y': np.random.uniform(0, 1, 4)}) 
df.plot(kind = 'scatter', x = 'x', y = 'y') 
plt.show() 

Odpowiedz

6

Odkryłem błąd. Błąd jest w pandas technicznie, nie seaborn jak początkowo sądzono, choć wiąże kod z pandas, seaborn i matplotlib ...

W pandas.tools.plotting.ScatterPlot._make_plot następujący kod pojawia się wybrać kolory do zastosowania w wykresie punktowym

if c is None: 
    c_values = self.plt.rcParams['patch.facecolor'] 
elif c_is_column: 
    c_values = self.data[c].values 
else: 
    c_values = c 

W twoim przypadku c będzie równa None, która jest wartością domyślną, a więc c_values zostaną podane przez plt.rcParams['patch.facecolor'].

Teraz, jako część konfiguracji, seaborn modyfikuje plt.rcParams['patch.facecolor'] na (0.5725490196078431, 0.7764705882352941, 1.0), co jest krotką RGB. Jeśli nie zostanie użyta wartość seaborn, wówczas wartością domyślną jest matplotlib, czyli 'b' (ciąg wskazujący kolor "niebieski").

c_values jest następnie wykorzystywany później rzeczywiście wykreślić wykres ciągu ax.scatter

scatter = ax.scatter(data[x].values, data[y].values, c=c_values, 
        label=label, cmap=cmap, **self.kwds) 

Problem pojawia się, ponieważ argument kluczowe c może przyjąć wiele różnych typów argumentów, może przyjąć: -

  • ciąg (taki jak 'b' w oryginalnym opakowaniu matplotlib);
  • sekwencja specyfikacji kolorów (powiedz sekwencję wartości RGB);
  • Sekwencja wartości do odwzorowania na bieżącą mapę kolorów.

Docs matplotlib konkretnie podać, co następuje podświetlenie kopalni

C może być pojedynczy łańcuch formatu kolorów, lub sekwencję specyfikacji kolor o długości n lub sekwencję liczb N być odwzorowany do kolorów za pomocą cmap i norm określonych przez kwargs (patrz poniżej). Należy zauważyć, że c nie powinno być pojedynczą numeryczną sekwencją RGB lub RGBA, ponieważ nie można jej odróżnić od tablicy wartości, które mają być mapowane. c może być tablicą 2-D, w której wiersze są jednak RGB lub RGBA.

Co się dzieje, że w zasadzie matplotlib przyjmuje wartość c_values (która jest krotką trzech cyfr), a następnie odwzorowuje te kolory na aktualnej mapie kolorów (która jest ustawiana przez pandy być Greys domyślnie). W związku z tym otrzymujesz trzy punkty rozproszone o różnym "szarości". Kiedy masz więcej niż 3 punkty rozproszenia, matplotlib zakłada, że ​​musi to być tupuła RGB, ponieważ długość nie odpowiada długości tablic danych (3! = 4) i dlatego używa go jako stałego koloru RBG.

Zostało to napisane jako zgłoszenie błędu na gandawie here pandy.

+0

Wielkie dzięki. Czy opublikujesz raport o błędzie na GitHub i prześlesz PR? Mogę spróbować zrobić to, jeśli wolisz. –

+0

@DavidBrochart ah przepraszam, zapomniałem wspomnieć. Wysłałem raport o błędzie na github pandy [tutaj] (https://github.com/pydata/pandas/issues/9724). Zobaczymy, co ludzie powiedzą przed kontynuowaniem. – Ffisegydd

+0

Niezła robota detektywistyczna @Ffisegydd – mwaskom

-1

Można spróbować to:

import seaborn.apionly as sns 

I zobaczyć This question więcej szczegółów.

+0

Jest to przydatna informacja, ale nie odpowiada na pytanie, jak rozwiązać problem. Co jeśli * chcesz * używać zabarwienia seaborn? – Ffisegydd