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

查看:29
本文介绍了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 对象是一个 Pandas 数据框,它被组织成每行代表一个数据点('x' 和 'y' 代表坐标,'colors' 是一个 0-5 之间的整数,代表点).我将数据点分为六个不同的集群,编号为 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.

这会输出下图:

我想知道如何向该图中添加图例,指定颜色及其对应的簇号.plt.legend() 要求样式代码采用 red_pa​​tch 等格式,但它似乎不采用数字值(或数字字符串).那么如何使用 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天全站免登陆