按列值为散点图着色

2025-02-11 09:50:00
admin
原创
58
摘要:问题描述:在 R 中使用库我最喜欢的方面之一ggplot2是能够轻松指定美学。我可以快速制作散点图并应用与特定列相关的颜色,我很乐意使用 python/pandas/matplotlib 来做到这一点。我想知道是否有任何便利函数可供人们使用 pandas 数据框和 Matplotlib 将颜色映射到值?##g...

问题描述:

在 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.scatterseaborn.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()

python 中的 ggplot

解决方案 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可以采用ccolor参数,该参数必须是颜色、颜色序列或数字序列。

  • 已在python 3.8pandas 1.3.1和进行测试matplotlib 3.4.2

  • 在 Matplotlib 中选择颜色图以获得其他有效cmap选项。

导入和测试数据

  • 'Date'已经是datetime64[ns] dtype来自DataReader

  • conda install -c anaconda pandas-datareaderpip 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')

如果在笔记本中创建,您将获得如下交互式输出:
在此处输入图片描述

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用