(carat, price, color)
のような変数で構成されるこのデータフレームdiamonds
があり、price
の散布図を各carat
ごとにcolor
からcolor
に描画します。
これはR
とggplot
で簡単です:
ggplot(aes(x=carat, y=price, color=color), #by setting color=color, ggplot automatically draw in different colors
data=diamonds) + geom_point(stat='summary', fun.y=median)
matplotlib
を使用してPythonでこれをどのように行うことができますか?
PS:
seaborn
やggplot for python
などの補助プロットパッケージについて知っていますが、matplotlib
を単独で使用してジョブを実行できるかどうかを知りたいだけです; P
plt.scatter
にc
引数を渡すと、色を選択できます。以下のコードは、colors
辞書を定義して、ダイヤモンドの色をプロットの色にマッピングします。
import matplotlib.pyplot as plt
import pandas as pd
carat = [5, 10, 20, 30, 5, 10, 20, 30, 5, 10, 20, 30]
price = [100, 100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600]
color =['D', 'D', 'D', 'E', 'E', 'E', 'F', 'F', 'F', 'G', 'G', 'G',]
df = pd.DataFrame(dict(carat=carat, price=price, color=color))
fig, ax = plt.subplots()
colors = {'D':'red', 'E':'blue', 'F':'green', 'G':'black'}
ax.scatter(df['carat'], df['price'], c=df['color'].apply(lambda x: colors[x]))
plt.show()
df['color'].apply(lambda x: colors[x])
は、色を「ダイヤモンド」から「プロット」に効果的にマップします。
(別のサンプル画像を載せないでください、私は2で十分だと思います:P)
seaborn
を使用seaborn
を使用すると、matplotlib
のラッパーになり、デフォルトできれいに見えるようになります(むしろ意見ベースで、Pを知っています)が、いくつかのプロット関数も追加されます。
このために、 seaborn.lmplot
をfit_reg=False
とともに使用できます(これにより、自動的に何らかのリグレッションが実行されなくなります)。
以下のコードはデータセットの例を使用しています。 hue='color'
を選択すると、色に基づいてデータフレームを分割し、それぞれをプロットするようにseabornに指示します。
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
carat = [5, 10, 20, 30, 5, 10, 20, 30, 5, 10, 20, 30]
price = [100, 100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600]
color =['D', 'D', 'D', 'E', 'E', 'E', 'F', 'F', 'F', 'G', 'G', 'G',]
df = pd.DataFrame(dict(carat=carat, price=price, color=color))
sns.lmplot('carat', 'price', data=df, hue='color', fit_reg=False)
plt.show()
pandas.groupby
を使用してseaborn
なしSeabornを使用したくない場合は、pandas.groupby
を使用して色を取得し、matplotlibだけを使用してプロットできますが、色を手動で割り当てる必要があるため、以下の例を追加しました。
fig, ax = plt.subplots()
colors = {'D':'red', 'E':'blue', 'F':'green', 'G':'black'}
grouped = df.groupby('color')
for key, group in grouped:
group.plot(ax=ax, kind='scatter', x='carat', y='price', label=key, color=colors[key])
plt.show()
このコードは、上記と同じDataFrameを想定し、color
に基づいてグループ化します。次に、これらのグループを反復処理して、各グループごとにプロットします。色を選択するために、ダイヤモンドの色(たとえばcolors
)を実際の色(たとえばD
)にマッピングできるred
辞書を作成しました。
シーボーンカラーパレットを使用するための簡潔で一般的なソリューションを次に示します。
最初に カラーパレットを見つける 好みに応じて視覚化します:
sns.palplot(sns.color_palette("Set2", 8))
次に、これをmatplotlib
で使用できます。
# Unique category labels: 'D', 'F', 'G', ...
color_labels = df['color'].unique()
# List of RGB triplets
rgb_values = sns.color_palette("Set2", 8)
# Map label to RGB
color_map = dict(Zip(color_labels, rgb_values))
# Finally use the mapped values
plt.scatter(df['carat'], df['price'], c=df['color'].map(color_map))
ここで、matplotlib
の定性的カラーマップからのマーカーと色の組み合わせ:
import itertools
import numpy as np
from matplotlib import markers
import matplotlib.pyplot as plt
m_styles = markers.MarkerStyle.markers
N = 60
colormap = plt.cm.Dark2.colors # Qualitative colormap
for i, (marker, color) in Zip(range(N), itertools.product(m_styles, colormap)):
plt.scatter(*np.random.random(2), color=color, marker=marker, label=i)
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0., ncol=4);
Altair を使用します。
from altair import *
import pandas as pd
df = datasets.load_dataset('iris')
Chart(df).mark_point().encode(x='petalLength',y='sepalLength', color='species')
私は同じ質問を持っていて、一日中さまざまなパッケージを試してみました。
私はもともとmatlibplotを使用していました。カテゴリを定義済みの色にマッピングすることに満足していませんでした。または、グループ化/集約してからグループを反復処理します(色をマップする必要があります)。パッケージの実装が不十分だと感じました。
Seabornは私のケースでは動作せず、AltairはJupyter Notebook内でのみ動作します。
私にとって最良の解決策はPlotNineでした。これは「Pythonでのグラフィックの文法の実装であり、ggplot2に基づいています」。
以下は、PythonでRの例を複製するためのplotnineコードです。
from plotnine import *
from plotnine.data import diamonds
g = ggplot(diamonds, aes(x='carat', y='price', color='color')) + geom_point(stat='summary')
print(g)
とてもきれいでシンプル:)