在matplotlib中使用字符串数组进行散点图

时间:2014-02-28 12:51:09

标签: python matplotlib pandas

这似乎应该是一个简单的,但我无法弄明白。我有一个熊猫数据框,并希望用3列进行3D散点图。 X和Y列不是数字,它们是字符串,但我不知道这应该是一个问题。

X= myDataFrame.columnX.values #string
Y= myDataFrame.columnY.values #string
Z= myDataFrame.columnY.values #float

fig = pl.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X, Y, np.log10(Z), s=20, c='b')
pl.show()

这不是一个简单的方法吗?感谢。

3 个答案:

答案 0 :(得分:8)

您可以使用np.unique(..., return_inverse=True)为每个字符串获取代表性的整数。例如,

In [117]: uniques, X = np.unique(['foo', 'baz', 'bar', 'foo', 'baz', 'bar'], return_inverse=True)

In [118]: X
Out[118]: array([2, 1, 0, 2, 1, 0])

请注意X dtype int32,因为np.unique最多只能处理2**31个唯一字符串。


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as axes3d

N = 12
arr = np.arange(N*2).reshape(N,2)
words = np.array(['foo', 'bar', 'baz', 'quux', 'corge'])
df = pd.DataFrame(words[arr % 5], columns=list('XY'))
df['Z'] = np.linspace(1, 1000, N)
Z = np.log10(df['Z'])
Xuniques, X = np.unique(df['X'], return_inverse=True)
Yuniques, Y = np.unique(df['Y'], return_inverse=True)

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
ax.scatter(X, Y, Z, s=20, c='b')
ax.set(xticks=range(len(Xuniques)), xticklabels=Xuniques,
       yticks=range(len(Yuniques)), yticklabels=Yuniques) 
plt.show()

enter image description here

答案 1 :(得分:2)

尝试将字符转换为绘图的数字,然后再次使用字符作为轴标签。

使用哈希

您可以使用hash功能进行转换;

from mpl_toolkits.mplot3d import Axes3D
xlab = myDataFrame.columnX.values
ylab = myDataFrame.columnY.values

X =[hash(l) for l in xlab] 
Y =[hash(l) for l in xlab] 

Z= myDataFrame.columnY.values #float

fig = figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X, Y, np.log10(Z), s=20, c='b')
ax.set_xticks(X)
ax.set_xticklabels(xlab)
ax.set_yticks(Y)
ax.set_yticklabels(ylab)
show()

正如M4rtini在评论中指出的那样,不清楚字符串坐标的间距/缩放应该是什么; hash函数可能会产生意外的间距。

非退化均匀间距

如果您希望均匀分布点,则必须使用不同的转换。 例如,您可以使用

X =[i for i in range(len(xlab))]

虽然这会导致每个点具有唯一的x位置,即使标签相同,如果对Y使用相同的方法,x和y点也会相关。

退化均匀间距

第三种方法是首先获取xlab的唯一成员(使用例如set),然后使用映射的唯一集将每个xlab映射到一个位置;例如

xmap = dict((sn, i)for i,sn in enumerate(set(xlab)))
X = [xmap[l] for l in xlab]

答案 2 :(得分:2)

Scatter现在自动执行此操作:

plt.scatter(['A', 'A', 'B', 'B'], [0, 1, 0, 1])

enter image description here