J'essaie de faire un simple nuage de points dans pyplot en utilisant un objet Pandas DataFrame, mais je veux un moyen efficace de tracer deux variables mais que les symboles soient dictés par une troisième colonne (clé). J'ai essayé différentes manières d'utiliser df.groupby, mais sans succès. Un exemple de script df est ci-dessous. Cela colore les marqueurs en fonction de «key1», mais j'aimerais voir une légende avec les catégories «key1». Suis-je proche? Merci.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(np.random.normal(10,1,30).reshape(10,3), index = pd.date_range('2010-01-01', freq = 'M', periods = 10), columns = ('one', 'two', 'three'))
df['key1'] = (4,4,4,6,6,6,8,8,8,8)
fig1 = plt.figure(1)
ax1 = fig1.add_subplot(111)
ax1.scatter(df['one'], df['two'], marker = 'o', c = df['key1'], alpha = 0.8)
plt.show()
la source
ax.legend(numpoints=1)
d'afficher un seul marqueur. Il y en a deux, comme avec aLine2D
, il y a souvent une ligne reliant les deux marqueurs.plt.hold(True)
après laax.plot()
commande. Une idée pourquoi?set_color_cycle()
était obsolète dans matplotlib 1.5. Il y aset_prop_cycle()
, maintenant.C'est simple à faire avec Seaborn (
pip install seaborn
) comme onelinersns.scatterplot(x_vars="one", y_vars="two", data=df, hue="key1")
:import seaborn as sns import pandas as pd import numpy as np np.random.seed(1974) df = pd.DataFrame( np.random.normal(10, 1, 30).reshape(10, 3), index=pd.date_range('2010-01-01', freq='M', periods=10), columns=('one', 'two', 'three')) df['key1'] = (4, 4, 4, 6, 6, 6, 8, 8, 8, 8) sns.scatterplot(x="one", y="two", data=df, hue="key1")
Voici le dataframe pour référence:
Puisque vous avez trois colonnes variables dans vos données, vous souhaiterez peut-être tracer toutes les dimensions par paires avec:
sns.pairplot(vars=["one","two","three"], data=df, hue="key1")
https://rasbt.github.io/mlxtend/user_guide/plotting/category_scatter/ est une autre option.
la source
Avec
plt.scatter
, je ne peux penser qu'à un seul: utiliser un artiste proxy:df = pd.DataFrame(np.random.normal(10,1,30).reshape(10,3), index = pd.date_range('2010-01-01', freq = 'M', periods = 10), columns = ('one', 'two', 'three')) df['key1'] = (4,4,4,6,6,6,8,8,8,8) fig1 = plt.figure(1) ax1 = fig1.add_subplot(111) x=ax1.scatter(df['one'], df['two'], marker = 'o', c = df['key1'], alpha = 0.8) ccm=x.get_cmap() circles=[Line2D(range(1), range(1), color='w', marker='o', markersize=10, markerfacecolor=item) for item in ccm((array([4,6,8])-4.0)/4)] leg = plt.legend(circles, ['4','6','8'], loc = "center left", bbox_to_anchor = (1, 0.5), numpoints = 1)
Et le résultat est:
la source
Vous pouvez utiliser df.plot.scatter, et passer un tableau à c = argument définissant la couleur de chaque point:
import numpy as np import pandas as pd import matplotlib.pyplot as plt df = pd.DataFrame(np.random.normal(10,1,30).reshape(10,3), index = pd.date_range('2010-01-01', freq = 'M', periods = 10), columns = ('one', 'two', 'three')) df['key1'] = (4,4,4,6,6,6,8,8,8,8) colors = np.where(df["key1"]==4,'r','-') colors[df["key1"]==6] = 'g' colors[df["key1"]==8] = 'b' print(colors) df.plot.scatter(x="one",y="two",c=colors) plt.show()
la source
Vous pouvez également essayer Altair ou ggpot qui sont axés sur les visualisations déclaratives.
import numpy as np import pandas as pd np.random.seed(1974) # Generate Data num = 20 x, y = np.random.random((2, num)) labels = np.random.choice(['a', 'b', 'c'], num) df = pd.DataFrame(dict(x=x, y=y, label=labels))
Code Altair
from altair import Chart c = Chart(df) c.mark_circle().encode(x='x', y='y', color='label')
code ggplot
from ggplot import * ggplot(aes(x='x', y='y', color='label'), data=df) +\ geom_point(size=50) +\ theme_bw()
la source
À partir de matplotlib 3.1, vous pouvez utiliser
.legend_elements()
. Un exemple est présenté dans la création de légende automatisée . L'avantage est qu'un seul appel scatter peut être utilisé.Dans ce cas:
import numpy as np import pandas as pd import matplotlib.pyplot as plt df = pd.DataFrame(np.random.normal(10,1,30).reshape(10,3), index = pd.date_range('2010-01-01', freq = 'M', periods = 10), columns = ('one', 'two', 'three')) df['key1'] = (4,4,4,6,6,6,8,8,8,8) fig, ax = plt.subplots() sc = ax.scatter(df['one'], df['two'], marker = 'o', c = df['key1'], alpha = 0.8) ax.legend(*sc.legend_elements()) plt.show()
Dans le cas où les clés ne seraient pas directement données sous forme de nombres, cela ressemblerait à
import numpy as np import pandas as pd import matplotlib.pyplot as plt df = pd.DataFrame(np.random.normal(10,1,30).reshape(10,3), index = pd.date_range('2010-01-01', freq = 'M', periods = 10), columns = ('one', 'two', 'three')) df['key1'] = list("AAABBBCCCC") labels, index = np.unique(df["key1"], return_inverse=True) fig, ax = plt.subplots() sc = ax.scatter(df['one'], df['two'], marker = 'o', c = index, alpha = 0.8) ax.legend(sc.legend_elements()[0], labels) plt.show()
la source
fig, ax = plt.subplots(1, 1, figsize = (4,4)) scat = ax.scatter(rand_jitter(important_dataframe["workout_type_int"], jitter = 0.04), important_dataframe["distance"], c = color_list, marker = 'o', alpha = 0.9) print(scat.legends_elements()) #ax.legend(*scat.legend_elements())
legends_elements
etlegend_elements
.Il est assez hacky, mais vous pouvez utiliser
one1
commeFloat64Index
pour tout faire en une seule fois:df.set_index('one').sort_index().groupby('key1')['two'].plot(style='--o', legend=True)
Notez qu'à partir de 0.20.3, le tri de l'index est nécessaire et la légende est un peu bancale .
la source
seaborn a une fonction d'emballage
scatterplot
qui le fait plus efficacement.sns.scatterplot(data = df, x = 'one', y = 'two', data = 'key1'])
la source