Ano*_*sse 6 python matplotlib scatter-plot scipy
我只是从scipy堆栈开始.我正在使用CSV版本的虹膜数据集.我可以使用以下方法加载它:
iris=numpy.recfromcsv("iris.csv")
Run Code Online (Sandbox Code Playgroud)
并绘制它:
pylab.scatter(iris.field(0), iris.field(1))
pylab.show()
Run Code Online (Sandbox Code Playgroud)
现在我还要绘制存储在iris.field(4)以下类中的类:
chararray(['setosa', ...], dtype='|S10')
Run Code Online (Sandbox Code Playgroud)
将这些字符串映射到用于绘图的颜色的优雅方法是什么?scatter(iris.field(0), iris.field(1), c=iris.field(4))不起作用(从它预期浮动值或色彩图的文档).我没有找到一种自动生成彩色地图的优雅方式.
cols = {"versicolor": "blue", "virginica": "green", "setosa": "red"}
scatter(iris.field(0), iris.field(1), c=map(lambda x:cols[x], iris.field(4)))
Run Code Online (Sandbox Code Playgroud)
大概是我想要的,但我不太喜欢手动颜色规格.
编辑:最后一行稍微优雅的版本:
scatter(iris.field(0), iris.field(1), c=map(cols.get, iris.field(4)))
Run Code Online (Sandbox Code Playgroud)
一种方式是否优雅在某种程度上是主观的.我个人认为你的方法比'matplotlib'更好.来自matplotlib的颜色模块:
着色映射通常涉及两个步骤:首先使用Normalize或子类的实例将数据数组映射到范围0-1; 然后使用Colormap子类的实例将0-1范围内的此数字映射到颜色.
关于你的问题,我从这里得到的是你需要一个Normalize接受字符串并将它们映射到0-1 的子类.
这是一个继承自Normalize创建子类的示例,TextNorm用于将字符串转换为0到1之间的值.此规范化用于获取相应的颜色.
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
import numpy as np
from numpy import ma
class TextNorm(Normalize):
'''Map a list of text values to the float range 0-1'''
def __init__(self, textvals, clip=False):
self.clip = clip
# if you want, clean text here, for duplicate, sorting, etc
ltextvals = set(textvals)
self.N = len(ltextvals)
self.textmap = dict(
[(text, float(i)/(self.N-1)) for i, text in enumerate(ltextvals)])
self.vmin = 0
self.vmax = 1
def __call__(self, x, clip=None):
#Normally this would have a lot more to do with masking
ret = ma.asarray([self.textmap.get(xkey, -1) for xkey in x])
return ret
def inverse(self, value):
return ValueError("TextNorm is not invertible")
iris = np.recfromcsv("iris.csv")
norm = TextNorm(iris.field(4))
plt.scatter(iris.field(0), iris.field(1), c=norm(iris.field(4)), cmap='RdYlGn')
plt.savefig('textvals.png')
plt.show()
Run Code Online (Sandbox Code Playgroud)
这会产生:

我选择了'RdYlGn'颜色贴图,以便很容易区分这三种类型的点.我没有将该clip功能作为其中的一部分__call__,尽管只需进行一些修改即可.
传统上,您可以scatter使用norm关键字scatter测试方法的规范化,但测试c关键字以查看它是否存储字符串,如果存在,则假定您将颜色作为字符串值传递,例如"红色","蓝色"等等.所以调用plt.scatter(iris.field(0), iris.field(1), c=iris.field(4), cmap='RdYlGn', norm=norm)失败.相反,我只是使用TextNorm和"操作" iris.field(4)来返回0到1范围内的值数组.
请注意,对于不在列表中的sting,将返回值-1 textvals.这就是屏蔽会派上用场的地方.
无论值多少钱,在这种情况下,您通常都会做类似的事情:
import numpy as np
import matplotlib.pyplot as plt
iris = np.recfromcsv('iris.csv')
names = set(iris['class'])
x,y = iris['sepal_length'], iris['sepal_width']
for name in names:
cond = iris['class'] == name
plt.plot(x[cond], y[cond], linestyle='none', marker='o', label=name)
plt.legend(numpoints=1)
plt.show()
Run Code Online (Sandbox Code Playgroud)

@Yann的建议没有什么问题,但是scatter更适合连续数据。
依赖于轴的颜色循环并多次调用绘图会更容易(您还会获得单独的艺术家而不是集合,这对于像这样的离散数据来说是一件好事)。
默认情况下,轴的颜色循环为:蓝色,绿色,红色,青色,品红色,黄色,黑色。
调用7次后plot,它将循环显示这些颜色,因此,如果您有更多项目,则需要手动设置(或在每次调用中指定颜色,以plot使用类似于上面@Yann建议的插值颜色栏) 。