Como posso gerar um mapa de calor a partir dos resultados do AnyDice?

7

I want to show some effects of changing dice rolls on a mapa de calor, where on one axis I have task difficulty (level of a spell, quality of lock to pick etc), and on another character level / proficiency bonus. Color should represent chance of success.

Usually, graphs from AnyDice are hardly useful to just look and easily understand; it generates many lines or bars, when I want it all on one map.

Here is an example program: https://anydice.com/program/1451d - fifty lines of probabilities; not so nice to look at, and not useful to post in answers here.

Como posso gerar um mapa de calor a partir dos resultados do AnyDice?

I want something like what is described here on a sister site: What is a probability heat map? I would prefer an option in AnyDice, if they implemented it and I just don't see it. A tool that can take an export from AnyDice and generate a heat map would be great, too.

Using spreadsheet and conditional formatting, I managed to get roughly what I wanted, but it was a boring and lengthy process: Exemplo

por Mołot 02.04.2019 / 14:51

1 resposta

O AnyDice export format is pretty easy to parse: it's basically just CSV text. In fact, you could directly import it into a spreadsheet program, but then you'd have to rearrange the data into a grid there.

To avoid that chore, I wrote a quick Python script to read the exported data from your AnyDice code (specifically, the first section of the AnyDice summary export, from after the "mean" e "output",# lines up to the next blank line), extract the row and column numbers from the output name with a regexp and print the result as a grid:

import csv, sys, re

csvreader = csv.reader(sys.stdin)

table = {}
columns = []
for name, value in csvreader:
    row, col = re.findall(r'-?\d+', name)
    if row not in table: table[row] = {}
    if col not in columns: columns.append(col)
    table[row][col] = value

csvwriter = csv.writer(sys.stdout)
csvwriter.writerow([''] + columns)

for row in table:
    csvwriter.writerow([row] + [table[row][col] for col in columns])

(The regexp -?\d+ fósforos one or more digits with an optional minus sign in front, i.e. a whole number. If there aren't exactly two such numbers in the name of each AnyDice output, the script will crash with a ValueError. Anything else in the name of the output gets ignored, so the name "0 foo 2" é tão bom quanto "Spell Level 0, proficiency bonus 2" as far as the script is concerned.)

Running the script on your data (try it online!), it prints the following grid, also in CSV format:

,2,3,4,5,6
0,0.6,0.65,0.7,0.75,0.8
1,0.55,0.6,0.65,0.7,0.75
2,0.5,0.55,0.6,0.65,0.7
3,0.45,0.5,0.55,0.6,0.65
4,0.4,0.45,0.5,0.55,0.6
5,0.35,0.4,0.45,0.5,0.55
6,0.3,0.35,0.4,0.45,0.5
7,0.25,0.3,0.35,0.4,0.45
8,0.2,0.25,0.3,0.35,0.4
9,0.15,0.2,0.25,0.3,0.35

We can then import this into any spreadsheet software, like Microsoft Excel or Open/LibreOffice Calc. Just to do this whole thing online, I decided to use planilhas do Google.

After importing the CSV file, I selected the data area (excluding the header row and column), selected FormatoConditional formatting... from the menu, and chose the "Color scale" tab in the sidebar that it opens. The default color scale ("green to white") looked a bit ugly and low-contrast to me, so I changed it to "red to white to green", and got this:

Screenshot of heat map in Google Sheets using conditional formatting

Not bad for a first try, in my opinion. Here's the actual spreadsheet, if you want to see it "live". Of course, there's a lot we could do to improve the formatting, like adjusting the column widths and the horizontal alignment of the numbers and adding some labels for the headers, but this should at least demonstrate the basic workflow.

03.04.2019 / 14:58