Ответ 1
ОБНОВЛЕНИЕ: ответ ниже по-прежнему является правильным во всех основных пунктах, но API немного изменился, чтобы быть более явным, начиная с Bokeh 0.7. В общем, такие вещи, как:
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 Mes. Смотрите в нижней части этого ответа, если вы хотите числовые координаты.
Кроме того, пример 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
)
Еще одно примечание: здесь отображаются только прямоangularьники на диагонали, где x- и y-координаты совпадают. Кажется, это то, что вы хотите от вашего описания. Но для полноты картины можно построить прямоangularьники с разными 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()