按列值为散点图着色
- 2025-02-11 09:50:00
- admin 原创
- 58
问题描述:
在 R 中使用库我最喜欢的方面之一ggplot2
是能够轻松指定美学。我可以快速制作散点图并应用与特定列相关的颜色,我很乐意使用 python/pandas/matplotlib 来做到这一点。我想知道是否有任何便利函数可供人们使用 pandas 数据框和 Matplotlib 将颜色映射到值?
##ggplot scatterplot example with R dataframe, `df`, colored by col3
ggplot(data = df, aes(x=col1, y=col2, color=col3)) + geom_point()
##ideal situation with pandas dataframe, 'df', where colors are chosen by col3
df.plot(x=col1,y=col2,color=col3)
编辑:感谢您的回复,但我想添加一个示例数据框来澄清我的问题。两列包含数值数据,第三列是分类变量。我正在考虑的脚本将根据此值分配颜色。
np.random.seed(250)
df = pd.DataFrame({'Height': np.append(np.random.normal(6, 0.25, size=5), np.random.normal(5.4, 0.25, size=5)),
'Weight': np.append(np.random.normal(180, 20, size=5), np.random.normal(140, 20, size=5)),
'Gender': ["Male","Male","Male","Male","Male",
"Female","Female","Female","Female","Female"]})
Height Weight Gender
0 5.824970 159.210508 Male
1 5.780403 180.294943 Male
2 6.318295 199.142201 Male
3 5.617211 157.813278 Male
4 6.340892 191.849944 Male
5 5.625131 139.588467 Female
6 4.950479 146.711220 Female
7 5.617245 121.571890 Female
8 5.556821 141.536028 Female
9 5.714171 134.396203 Female
解决方案 1:
进口和数据
import numpy
import pandas
import matplotlib.pyplot as plt
import seaborn as sns
seaborn.set(style='ticks')
numpy.random.seed(0)
N = 37
_genders= ['Female', 'Male', 'Non-binary', 'No Response']
df = pandas.DataFrame({
'Height (cm)': numpy.random.uniform(low=130, high=200, size=N),
'Weight (kg)': numpy.random.uniform(low=30, high=100, size=N),
'Gender': numpy.random.choice(_genders, size=N)
})
2021 年 8 月更新
使用 时
seaborn 0.11.0
,建议使用新的图形级别函数,例如 ,seaborn.relplot
而不是直接使用FacetGrid
。
sns.relplot(data=df, x='Weight (kg)', y='Height (cm)', hue='Gender', hue_order=_genders, aspect=1.61)
plt.show()
2015 年 10 月更新
Seaborn 出色地处理了这个用例:
映射
matplotlib.pyplot.scatter
到seaborn.FacetGrid
fg = sns.FacetGrid(data=df, hue='Gender', hue_order=_genders, aspect=1.61)
fg.map(plt.scatter, 'Weight (kg)', 'Height (cm)').add_legend()
立即输出:
旧答案
在这种情况下,我会直接使用 matplotlib。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
def dfScatter(df, xcol='Height', ycol='Weight', catcol='Gender'):
fig, ax = plt.subplots()
categories = np.unique(df[catcol])
colors = np.linspace(0, 1, len(categories))
colordict = dict(zip(categories, colors))
df["Color"] = df[catcol].apply(lambda x: colordict[x])
ax.scatter(df[xcol], df[ycol], c=df.Color)
return fig
if 1:
df = pd.DataFrame({'Height':np.random.normal(size=10),
'Weight':np.random.normal(size=10),
'Gender': ["Male","Male","Unknown","Male","Male",
"Female","Did not respond","Unknown","Female","Female"]})
fig = dfScatter(df)
fig.savefig('fig1.png')
这让我:
据我所知,该颜色列可以是任何与 matplotlib 兼容的颜色(RBGA 元组、HTML 名称、十六进制值等)。
我无法获得除数值之外的任何与色彩图配合使用的数据。
解决方案 2:
实际上你可以使用ggplot for python:
from ggplot import *
import numpy as np
import pandas as pd
df = pd.DataFrame({'Height':np.random.randn(10),
'Weight':np.random.randn(10),
'Gender': ["Male","Male","Male","Male","Male",
"Female","Female","Female","Female","Female"]})
ggplot(aes(x='Height', y='Weight', color='Gender'), data=df) + geom_point()
解决方案 3:
https://seaborn.pydata.org/ generated/seaborn.scatterplot.html
import numpy
import pandas
import seaborn as sns
numpy.random.seed(0)
N = 37
_genders= ['Female', 'Male', 'Non-binary', 'No Response']
df = pandas.DataFrame({
'Height (cm)': numpy.random.uniform(low=130, high=200, size=N),
'Weight (kg)': numpy.random.uniform(low=30, high=100, size=N),
'Gender': numpy.random.choice(_genders, size=N)
})
sns.scatterplot(data=df, x='Height (cm)', y='Weight (kg)', hue='Gender')
解决方案 4:
您可以使用plot 方法的颜色参数来定义每列所需的颜色。例如:
from pandas import DataFrame
data = DataFrame({'a':range(5),'b':range(1,6),'c':range(2,7)})
colors = ['yellowgreen','cyan','magenta']
data.plot(color=colors)
您可以使用颜色名称或颜色十六进制代码,例如“#000000”表示黑色。您可以在 matplotlib 的 color.py 文件中找到所有定义的颜色名称。以下是 matplotlib 的 github repo 中 color.py 文件的链接。
https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/colors.py
解决方案 5:
OP 通过分类列进行着色,但这个答案是通过数字列进行着色,或者可以解释为数字,例如
datetime dtype
。pandas.DataFrame.plot
并且matplotlib.pyplot.scatter
可以采用c
或color
参数,该参数必须是颜色、颜色序列或数字序列。已在
python 3.8
、pandas 1.3.1
和进行测试matplotlib 3.4.2
在 Matplotlib 中选择颜色图以获得其他有效
cmap
选项。
导入和测试数据
'Date'
已经是datetime64[ns] dtype
来自DataReader
conda install -c anaconda pandas-datareader
或pip install pandas-datareader
取决于您的环境。
import pandas as pd
import matplotlib.pyplot as plt
import pandas_datareader as web # for data; not part of pandas
tickers = 'amzn'
df = web.DataReader(ticker, data_source='yahoo', start='2018-01-01', end='2021-01-01').reset_index()
df['ticker'] = ticker
Date High Low Open Close Volume Adj Close ticker
0 2018-01-02 1190.00000 1170.510010 1172.000000 1189.010010 2694500 1189.010010 amzn
1 2018-01-03 1205.48999 1188.300049 1188.300049 1204.199951 3108800 1204.199951 amzn
c
作为一个数字
pandas.DataFrame.plot
df.Date.dt.month
创建pandas.Series
月份数字
ax = df.plot(kind='scatter', x='Date', y='High', c=df.Date.dt.month, cmap='Set3', figsize=(11, 4), title='c parameter as a month number')
plt.show()
matplotlib.pyplot.scatter
fig, ax = plt.subplots(figsize=(11, 4))
ax.scatter(data=df, x='Date', y='High', c=df.Date.dt.month, cmap='Set3')
ax.set(title='c parameter as a month number', xlabel='Date', ylabel='High')
plt.show()
c
作为datetime dtype
pandas.DataFrame.plot
ax = df.plot(kind='scatter', x='Date', y='High', c='Date', cmap='winter', figsize=(11, 4), title='c parameter as a datetime dtype')
plt.show()
matplotlib.pyplot.scatter
fig, ax = plt.subplots(figsize=(11, 4))
ax.scatter(data=df, x='Date', y='High', c='Date', cmap='winter')
ax.set(title='c parameter as a datetime dtype', xlabel='Date', ylabel='High')
plt.show()
解决方案 6:
虽然不是 matplotlib,但您可以使用plotly express实现这一点:
import numpy as np
import pandas as pd
import plotly.express as px
df = pd.DataFrame({
'Height':np.random.normal(size=10),
'Weight':np.random.normal(size=10),
'Size': 1, # How large each point should be?
'Gender': ["Male","Male","Male","Male","Male","Female","Female","Female","Female","Female"]})
# Create your plot
px.scatter(df, x='Weight', y='Height', size='Size', color='Gender')
如果在笔记本中创建,您将获得如下交互式输出: