使用bokeh或matplotlib绘制主题
我正在尝试从一个模型中绘制主题可视化图。
我想做的事情类似于bokeh的协方差实现,具体可以参考这个链接。
我的数据是:
data 1: index, topics.
data 2: index, topics, weights(use it for color).
其中“主题”就是一组单词。
我该如何将这些数据传给bokeh,以便绘制上面的数据呢?从例子来看,数据处理的方式并不直观。
用matplotlib的话,效果看起来像这个链接。
显然,单从图中看,无法清楚地知道每个圆圈对应哪个主题。
这是我的matplotlib代码:
x = []
y = []
area = []
for row in joined:
x.append(row['index'])
y.append(row['index'])
#weight.append(row['score'])
area.append(np.pi * (15 * row['score'])**2)
scale_values = 1000
plt.scatter(x, y, s=scale_values*np.array(area), alpha=0.5)
plt.show()
有没有什么想法或建议呢?
1 个回答
15
更新: 下面的回答在主要观点上仍然是正确的,但自从Bokeh 0.7版本以来,API稍微有了一些变化,变得更加明确。一般来说,像这样的内容:
rect(...)
应该替换为
p = figure(...)
p.rect(...)
这里是Les Mis示例中相关的代码行,简化到你的情况。我们来看一下:
# A "ColumnDataSource" is like a dict, it maps names to columns of data.
# These names are not special we can call the columns whatever we like.
source = ColumnDataSource(
data=dict(
x = [row['name'] for row in joined],
y = [row['name'] for row in joined],
color = list_of_colors_one_for_each_row,
)
)
# We need a list of the categorical coordinates
names = list(set(row['name'] for row in joined))
# rect takes center coords (x,y) and width and height. We will draw
# one rectangle for each row.
rect('x', 'y', # use the 'x' and 'y' fields from the data source
0.9, 0.9, # use 0.9 for both width and height of each rectangle
color = 'color', # use the 'color' field to set the color
source = source, # use the data source we created above
x_range = names, # sequence of categorical coords for x-axis
y_range = names, # sequence of categorical coords for y-axis
)
几点说明:
对于数字数据,
x_range
和y_range
通常会自动提供。我们在这里需要明确给出它们,因为我们使用的是分类坐标。你可以随意排列
x_range
和y_range
中的名称,这个顺序就是它们在图表坐标轴上显示的顺序。我假设你想使用分类坐标。:) 这正是Les Mis示例所做的。如果你想要数字坐标,可以查看这个回答的底部。
另外,Les Mis示例稍微复杂一些(它有一个悬停工具),所以我们手动创建了一个ColumnDataSource。如果你只需要一个简单的图表,可能可以跳过自己创建数据源,直接把数据传给rect
:
names = list(set(row['name'] for row in joined))
rect(names, # x (categorical) coordinate for each rectangle
names, # y (categorical) coordinate for each rectangle
0.9, 0.9, # use 0.9 for both width and height of each rectangle
color = some_colors, # color for each rect
x_range = names, # sequence of categorical coords for x-axis
y_range = names, # sequence of categorical coords for y-axis
)
还有一点:这只会在对角线上绘制矩形,也就是x坐标和y坐标相同的地方。根据你的描述,这似乎是你想要的。但为了完整性,也可以绘制x坐标和y坐标不同的矩形。Les Mis示例就是这样做的。
最后,也许你其实并不想要分类坐标轴?如果你只想使用坐标的数字索引,那会更简单:
inds = [row['index'] for row in joined]
rect(inds, # x-coordinate for each rectangle
inds, # y-coordinate for each rectangle
0.9, 0.9, # use 0.9 for both width and height of each rectangle
color = some_colors, # color for each rect
)
编辑: 这里有一个完整的可运行示例,使用数字坐标:
from bokeh.plotting import *
output_file("foo.html")
inds = [2, 5, 6, 8, 9]
colors = ["red", "orange", "blue", "green", "#4488aa"]
rect(inds, inds, 1.0, 1.0, color=colors)
show()
还有一个示例,使用相同的值作为分类坐标:
from bokeh.plotting import *
output_file("foo.html")
inds = [str(x) for x in [2, 5, 6, 8, 9]]
colors = ["red", "orange", "blue", "green", "#4488aa"]
rect(inds, inds, 1.0, 1.0, color=colors, x_range=inds, y_range=inds)
show()