Подтвердить что ты не робот

Сюжетные темы с bokeh или matplotlib

Я пытаюсь построить визуализацию темы из модели. Я хочу сделать что-то вроде боке ковариации реализации.

Мои данные:

data 1: index,                            topics.   
data 2: index, topics, weights(use it for color). 

где тема просто набор слов.

Как передать данные боке для построения приведенных выше данных? В этом примере обработка данных не является интуитивно понятной.

С matplot это выглядит как это.
Очевидно, что визуально не полезно видеть, какая тема соответствует каждому кругу. Вот мой код 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()

Есть идеи или предложения?

4b9b3361

Ответ 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()