Matplotlib добавляет легенду в разные цветовые точки [дубликат]

Исходные типы прекрасны, когда они выражают то, что вы хотите выразить.

Например, функция десериализации может возвращать List, но она не знает тип элемента списка. Таким образом, List является подходящим типом возврата.

55
задан user2989613 9 February 2014 в 04:51
поделиться

6 ответов

Вы можете использовать scatter для этого, но для этого нужно иметь числовые значения для вашего key1, и у вас не будет легенды, как вы заметили.

Лучше просто использовать plot для таких дискретных категорий. Например:

import matplotlib.pyplot as plt
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))

groups = df.groupby('label')

# Plot
fig, ax = plt.subplots()
ax.margins(0.05) # Optional, just adds 5% padding to the autoscaling
for name, group in groups:
    ax.plot(group.x, group.y, marker='o', linestyle='', ms=12, label=name)
ax.legend()

plt.show()

enter image description here [/g0]

Если вы хотите, чтобы все выглядело как стиль по умолчанию pandas, просто обновите rcParams с таблицей стилей панд и используйте свой генератор цветов. (Я также немного изменяю легенду):

import matplotlib.pyplot as plt
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))

groups = df.groupby('label')

# Plot
plt.rcParams.update(pd.tools.plotting.mpl_stylesheet)
colors = pd.tools.plotting._get_standard_colors(len(groups), color_type='random')

fig, ax = plt.subplots()
ax.set_color_cycle(colors)
ax.margins(0.05)
for name, group in groups:
    ax.plot(group.x, group.y, marker='o', linestyle='', ms=12, label=name)
ax.legend(numpoints=1, loc='upper left')

plt.show()

enter image description here [/g1]

74
ответ дан Joe Kington 21 August 2018 в 04:40
поделиться
  • 1
    Да, похоже, это сработает для меня. Огромное спасибо. – user2989613 9 February 2014 в 06:44
  • 2
    Почему в примере RGB выше символ, показанный дважды в легенде? Как показать только один раз? – Steve Schulist 10 June 2015 в 23:07
  • 3
    @SteveSchulist. Используйте ax.legend(numpoints=1), чтобы показать только один маркер. Есть два, как и с Line2D, часто есть линия, соединяющая два маркера. – Joe Kington 11 June 2015 в 13:58
  • 4
    Этот код работал только после добавления plt.hold(True) после команды ax.plot(). Любая идея почему? – yuval 29 November 2016 в 18:50

Вы можете использовать df.plot.scatter и передать массив в c = аргумент, определяющий цвет каждой точки:

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()

5
ответ дан Arjaan Buijk 21 August 2018 в 04:40
поделиться

Это просто сделать с Seaborn (pip install seaborn) как oneliner

sns.pairplot(x_vars=["one"], y_vars=["two"], data=df, hue="key1", size=5):

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.pairplot(x_vars=["one"], y_vars=["two"], data=df, hue="key1", size=5)

Вот кадр данных для ссылки:

Поскольку у вас есть три столбца переменной в ваших данных, вы можете хотите построить все парные размеры с помощью:

sns.pairplot(vars=["one","two","three"], data=df, hue="key1", size=5)

https://rasbt.github.io/mlxtend/user_guide/plotting / category_scatter / - это еще один вариант.

31
ответ дан Bob Baxley 21 August 2018 в 04:40
поделиться

С помощью plt.scatter я могу только думать об одном: использовать прокси-исполнителя:

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)

И результат:

enter image description here [/g0]

17
ответ дан CT Zhu 21 August 2018 в 04:40
поделиться
  • 1
    Еще одно хорошее предложение. Я тоже попробую. Благодарю. – user2989613 9 February 2014 в 06:44
  • 2
    хороший трюк, который не требует цикла for. – Tu Bui 9 April 2018 в 15:09

Это довольно хаки, но вы можете использовать one1 как Float64Index, чтобы сделать все за один раз:

df.set_index('one').sort_index().groupby('key1')['two'].plot(style='--o', legend=True)

Заметим, что с 0.20.3 сортировка индекса необходима , а легенда - бит wonky .

0
ответ дан fuglede 21 August 2018 в 04:40
поделиться

Вы также можете попробовать Altair или ggpot , которые сфокусированы на декларативной визуализации.

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))

Код Altair

from altair import Chart
c = Chart(df)
c.mark_circle().encode(x='x', y='y', color='label')

код ggplot

from ggplot import *
ggplot(aes(x='x', y='y', color='label'), data=df) +\
geom_point(size=50) +\
theme_bw()

2
ответ дан Nipun Batra 21 August 2018 в 04:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: