таблица matplotlib: индивидуальная цветовая карта для диапазона каждого столбца - PullRequest
0 голосов
/ 17 марта 2020

Я использую matplotlib для создания таблицы с 5 строками и 4 столбцами. Я хотел бы показать разницу в значениях для всех записей в каждом отдельном столбце, используя цвет. В идеале я хотел бы использовать шкалу цветовой карты, которая индивидуализирована для каждого столбца, а это означает, что шкала цветовой карты этого столбца будет иметь диапазон значений этого столбца.

Для пояснения - во втором столбце значения между 800-1200, но значения первого столбца находятся между 120-230. Когда одна и та же цветовая карта применяется ко всему диапазону таблицы, разница между значениями в первом столбце определяется намного меньше, чем если бы диапазон цветовой карты был 120-230 вместо 120-1200.

Это с matplotlib кажется невозможным, так как цветовая карта применяется ко всей таблице. То, что я хочу, может быть просто ужасной и запутанной презентацией, поэтому, если есть лучший способ показать, что я хотел бы, пожалуйста, дайте мне знать!

Это то, что я имею сейчас:

fig, ax = plt.subplots()

rows = ['%d nodes' % x for x in (10, 30, 50, 75, 100)]
columns=['TP', 'TN', 'FP', 'FN']

conf_data = np.array(
[[ 230,  847,  784,  208],
 [ 156, 1240,  391,  282],
 [ 146, 1212,  419,  292],
 [ 130, 1148,  483,  308],
 [ 122, 1173,  458,  316]]
)  

normal = plt.Normalize(np.min(conf_data), np.max(conf_data))
fig.patch.set_visible(False)
ax.axis('off')
ax.axis('tight')
ax.table(cellText=conf_data,
         rowLabels=rows,
         colLabels=columns,
         cellColours=cm.GnBu(normal(conf_data)),
         loc='center',
         colWidths=[0.1 for x in columns])
fig.tight_layout()
plt.show()

Ответы [ 2 ]

0 голосов
/ 17 марта 2020

Вы можете рассчитать норму для каждого столбца:

import matplotlib.cm as cm
fig, ax = plt.subplots()

rows = ['%d nodes' % x for x in (10, 30, 50, 75, 100)]
columns=['TP', 'TN', 'FP', 'FN']

conf_data = np.array(
[[ 230,  847,  784,  208],
 [ 156, 1240,  391,  282],
 [ 146, 1212,  419,  292],
 [ 130, 1148,  483,  308],
 [ 122, 1173,  458,  316]]
)  

colores = np.zeros((conf_data.shape[0], conf_data.shape[1], 4))
for i in range(conf_data.shape[1]):
    col_data = conf_data[:, i]
    normal = plt.Normalize(np.min(col_data), np.max(col_data))
    colores[:, i] = cm.Reds(normal(col_data))

#fig.patch.set_visible(False)
ax.axis('off')
ax.axis('tight')
ax.table(cellText=conf_data,
         rowLabels=rows,
         colLabels=columns,
         cellColours=colores,
         loc='center',
         colWidths=[0.1 for x in columns])
fig.tight_layout()
plt.show()
0 голосов
/ 17 марта 2020

Вы можете вычесть минимум каждого столбца и поделить на их ptp. np.ptp или расстояние от пика до пика - это разница между максимумом и минимумом. Сохраните это в новый массив, который будет использоваться для значений цвета.

Чтобы избежать слишком синего для самых высоких значений, вы можете умножить результат на что-то вроде 0,8. (В качестве альтернативы вы можете изменить цвет текста, для чего требуется дополнительный дополнительный код .)

import numpy as np
from matplotlib import pyplot as plt

fig, ax = plt.subplots()

rows = ['%d nodes' % x for x in (10, 30, 50, 75, 100)]
columns = ['TP', 'TN', 'FP', 'FN']
conf_data = np.array([[230, 847, 784, 208],
                      [156, 1240, 391, 282],
                      [146, 1212, 419, 292],
                      [130, 1148, 483, 308],
                      [122, 1173, 458, 316]])
normed_data = (conf_data - conf_data.min(axis=0, keepdims=True)) / conf_data.ptp(axis=0, keepdims=True)

fig.patch.set_visible(False)
ax.axis('off')
ax.axis('tight')
table = ax.table(cellText=conf_data,
                 rowLabels=rows,
                 colLabels=columns,
                 cellColours=plt.cm.GnBu(normed_data*0.8),
                 loc='center',
                 colWidths=[0.1 for x in columns])
table.scale(2, 2) # make table a little bit larger
fig.tight_layout()
plt.show()

Ниже приведен результат с двумя разными цветными картами: «GnBu» слева с нормированными значениями от 0 до 0,8 и «холодное тепло» справа с нормированными значениями от 0,1 до 0,9

resulting plot

PS: еще один способ улучшить контраст между ячейками цвет текста и фона, для установки альфа каждой ячейки:

for cell in table._cells:
    table._cells[cell].set_alpha(.6)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...