Matplotlib基于现有颜色系列添加图例 [英] Matplotlib adding legend based on existing color series

查看:203
本文介绍了Matplotlib基于现有颜色系列添加图例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用散点图绘制了一些数据,并将其指定为:

I plotted some data using scatter plot and specified it as such:

plt.scatter(rna.data['x'], rna.data['y'], s=size,
                    c=rna.data['colors'], edgecolors='none')

和rna.data对象是一个熊猫数据框,其组织方式使得每一行代表一个数据点("x"和"y"代表坐标,"colors"是介于0到5之间的整数,代表颜色点).我将数据点分为6个不同的簇(编号为0-5),并将簇号放在每个簇的平均坐标上.

and the rna.data object is a pandas dataframe that is organized such that each row represents a data point ('x' and 'y' represents the coordinate and 'colors' is an integer between 0-5 representing the color of the point). I grouped the data points into six distinct clusters numbered 0-5, and put the cluster number at each cluster's mean coordinates.

这将输出以下图形:

This outputs the following graph:

我想知道如何在此图例中添加图例,以指定颜色及其对应的群集编号. plt.legend()要求样式代码采用诸如red_patch之类的格式,但它似乎不采用数字值(或数字字符串).然后,如何使用matplotlib添加此图例?有没有办法将我的数值颜色代码转换为plt.legend()所采用的格式?非常感谢!

I was wondering how I can add a legend to this plot specifying the color and its corresponding cluster number. plt.legend() requires the style code to be in the format such as red_patch but it does not seem to take numeric values (or the numeric strings). How can I add this legend using matplotlib then? Is there a way to translate my numeric value color codes to the format that plt.legend() takes? Thanks a lot!

推荐答案

您可以使用带有基于色图和散点图归一化颜色的空图来创建图例句柄.

You can create the legend handles using an empty plot with the color based on the colormap and normalization of the scatter plot.

import pandas as pd
import numpy as np; np.random.seed(1)
import matplotlib.pyplot as plt

x = [np.random.normal(5,2, size=20), np.random.normal(10,1, size=20),
     np.random.normal(5,1, size=20), np.random.normal(10,1, size=20)]
y = [np.random.normal(5,1, size=20), np.random.normal(5,1, size=20),
     np.random.normal(10,2, size=20), np.random.normal(10,2, size=20)]
c = [np.ones(20)*(i+1) for i in range(4)]

df = pd.DataFrame({"x":np.array(x).flatten(), 
                   "y":np.array(y).flatten(), 
                   "colors":np.array(c).flatten()})

size=81
sc = plt.scatter(df['x'], df['y'], s=size, c=df['colors'], edgecolors='none')

lp = lambda i: plt.plot([],color=sc.cmap(sc.norm(i)), ms=np.sqrt(size), mec="none",
                        label="Feature {:g}".format(i), ls="", marker="o")[0]
handles = [lp(i) for i in np.unique(df["colors"])]
plt.legend(handles=handles)
plt.show()

或者,您也可以按颜色列中的值过滤数据框,例如使用groubpy,并为每个功能绘制一个散点图:

Alternatively you may filter your dataframe by the values in the colors column, e.g. using groubpy, and plot one scatter plot for each feature:

import pandas as pd
import numpy as np; np.random.seed(1)
import matplotlib.pyplot as plt

x = [np.random.normal(5,2, size=20), np.random.normal(10,1, size=20),
     np.random.normal(5,1, size=20), np.random.normal(10,1, size=20)]
y = [np.random.normal(5,1, size=20), np.random.normal(5,1, size=20),
     np.random.normal(10,2, size=20), np.random.normal(10,2, size=20)]
c = [np.ones(20)*(i+1) for i in range(4)]

df = pd.DataFrame({"x":np.array(x).flatten(), 
                   "y":np.array(y).flatten(), 
                   "colors":np.array(c).flatten()})

size=81
cmap = plt.cm.viridis
norm = plt.Normalize(df['colors'].values.min(), df['colors'].values.max())

for i, dff in df.groupby("colors"):
    plt.scatter(dff['x'], dff['y'], s=size, c=cmap(norm(dff['colors'])), 
                edgecolors='none', label="Feature {:g}".format(i))

plt.legend()
plt.show()

两种方法都产生相同的情节:

Both methods produce the same plot:

这篇关于Matplotlib基于现有颜色系列添加图例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆