#python #numpy #dictionary #matplotlib #reinforcement-learning
Вопрос:
Мне нужен способ представления словаря (или двумерного массива NumPy) в графической форме, возможно, что-то, как показано ниже.
Мой словарь в настоящее время выглядит так Q: {(0,'U'): -0.1, (0,'R'): -0.254, (0,'D'): -0.9, (0,'L'): -0.23, ...}
, где U, R, D, L соответствует направлению Вверх, Вниз, Вправо и влево
Для дополнительного контекста я хочу визуализировать таблицу вопросов для метода обучения SARSA. Я записываю это в блокнот Jupyter. Я запускаю SARSA в общей сложности в 100 тысяч эпизодов и хотел бы визуализировать таблицу вопросов каждые 10 тысяч эпизодов.
Я полагаю, что matplotlib может это сделать? Но я не очень хорошо знаком с этим конкретным типом представления.
Если кто-нибудь может знать лучшие способы представления таблицы вопросов (в отличие от этого конкретного графического формата), я открыт для предложений. Я также могу представить Q-таблицу в виде 2D-массива numpy вместо словаря, если было бы лучше использовать 2D-массив.
Заранее спасибо за любые ответы!
Ответ №1:
Я действительно не знаю, что такое Q-таблица, но я трачу много времени, пытаясь визуализировать разные вещи.
Исходя из моего понимания вашей проблемы, вам нужно 10 таблиц, которые я расположил в виде решетки из 2 строк по 5 столбцов в приведенном ниже коде. Тем не менее, я надеюсь, что этот код должен масштабироваться до любого числа, которое вам нужно.
Я создал словарь того, что я считаю репрезентативными значениями для того, что может быть в Q-таблице? Надеюсь, мои предположения достаточно близки, чтобы вы могли использовать приведенный ниже код, чтобы подтолкнуть вашу проблему к финишу.
from matplotlib import pyplot as plt
import numpy as np
n_row = 2 # number of rows
n_col = 5 # number of columns
# Make up some dummy data
Q = {}
for m in range(n_row * n_col):
Q[(m, 'U')] = 2 * np.random.random() - 1
Q[(m, 'D')] = 2 * np.random.random() - 1
Q[(m, 'L')] = 2 * np.random.random() - 1
Q[(m, 'R')] = 2 * np.random.random() - 1
# Plotting paramters:
boxsize = 0.5 # box size in inches
fontcol = 'k' # color of your U/D/L/R values
centerfontcol = [0.3, 0.3, 0.3] # color of the box number in the center
fontsize = 4 # font size to use
maxalpha = 0.3 # just to make boxes different backgrounds as per your
# example if you want them all white, then remove this
# and the "fill" command below
# Create a figure. Note that the "figsize" command gives yout the dimensions of
# your figure, in inches
fig = plt.figure(figsize = (n_col * boxsize, n_row * boxsize))
# This creates an axes for plotting. If you imagine your figure
# "canvas" as having normal coordinates where the bottom left is (0,0)
# and the top right is (1,1), then the line below gives you an axis
# that fills the entire area. The values give [Left, Bottom,
# Width, Height].
ax = plt.axes([0, 0, 1, 1])
# These are spacings from the edges of each table used in setting the
# text
xspace = 0.2 / n_col
yspace = 0.15 / n_row
m = 0 # m is a counter that steps through your tables
# When stepping through each table, we set things up so that the
# limits of the figure are [0, 1] in the x-direction and the
# y-direction so values are normalized
for r in range(n_row):
# top and bottom bounds of the table
y1 = 1 - (r 1) / n_row
y2 = 1 - r / n_row
for c in range(n_col):
# left and right bounds of the table
x1 = c / n_col
x2 = (c 1) / n_col
# plot the box for the table
plt.plot([x1, x1, x2, x2, x1], [y1, y2, y2, y1, y1], 'k')
# fill the box for the table, if you want
# fillalpha is just if you want the boxes different shades
fillalpha = maxalpha * np.random.random()
plt.fill([x1, x1, x2, x2, x1], [y1, y2, y2, y1, y1], 'k', alpha = fillalpha)
# Put the values in
# center
plt.text((x1 x2) / 2, (y1 y2) / 2, "%i" % m,
color = centerfontcol, fontsize = fontsize, va = 'center', ha = 'center')
# left
plt.text(x1 xspace, (y1 y2) / 2, "%.2f" % Q[(m, 'L')],
color = fontcol, fontsize = fontsize, va = 'center', ha = 'center')
# right
plt.text(x2 - xspace, (y1 y2) / 2, "%.2f " % Q[(m, 'R')],
color = fontcol, fontsize = fontsize, va = 'center', ha = 'center')
# up
plt.text((x1 x2) / 2, y2 - yspace, "%.2f" % Q[(m, 'U')],
color = fontcol, fontsize = fontsize, va = 'center', ha = 'center')
# down
plt.text((x1 x2) / 2, y1 yspace, "%.2f" % Q[(m, 'D')],
color = fontcol, fontsize = fontsize, va = 'center', ha = 'center')
# augment the counter
m = 1
ax.set_axis_off()
plt.savefig("q-table.png", bbox_inches = "tight")
Комментарии:
1. эй, большое спасибо! это сработало для меня 🙂 Я просто поместил это в вспомогательную функцию и отредактировал строки и столбцы в соответствии с моими потребностями!
2. просто вопрос, я видел функцию заливки, и это будет полезно, так как я хочу раскрасить только определенные ячейки в таблице одним и тем же серым/черным цветом, как мне это сделать? У меня есть список, содержащий конкретные ячейки, которые я могу передать вспомогательной функции, в которую я поместил ваш код. Я знаю, что это нужно передать в plt.fill (), но не могли бы вы быстро показать мне пример? Допустим, boxes_to_color = [3, 5, 7]
3. Если я правильно вас понял, у вас есть вызов функции, который выполняет каждое поле? Если это так, у вас может быть только аргумент в конце со значением по умолчанию (например
fill_color = None
,), тогда в функции,if fill_color is not None: plt.fill(....., color = fill_color)
.4. эй, все в порядке, я понял!
m
отслеживает индекс словаря. Я хотел только раскрасить коробки с индексом, которые являются исходнымиholes
. Я пытался это сделатьif (r*n_row c*n_col) in holes
, но неправильно проиндексированные поля как-то окрашиваются.