161 lines
4.1 KiB
Python
161 lines
4.1 KiB
Python
|
#!/usr/bin/env python
|
||
|
from pprint import pprint
|
||
|
import csv
|
||
|
|
||
|
import matplotlib.pyplot as plt
|
||
|
import numpy as np
|
||
|
|
||
|
filename="synthesis_artworks.csv"
|
||
|
def scan_csv_list(content):
|
||
|
|
||
|
column_labels = {
|
||
|
"field": {
|
||
|
},
|
||
|
"theme": {
|
||
|
},
|
||
|
"size": {
|
||
|
},
|
||
|
"anthropomorphic": {
|
||
|
"name": "shape",
|
||
|
"values": {
|
||
|
True: "anthropormorphic",
|
||
|
False: "non-anthropormorphic",
|
||
|
},
|
||
|
},
|
||
|
"design": {
|
||
|
"values": {
|
||
|
"indus_brut" : "industrial",
|
||
|
"indus_custom" : "custom"
|
||
|
},
|
||
|
},
|
||
|
"mob_fix": {
|
||
|
"name": "mobility",
|
||
|
"values":{
|
||
|
True: "yes",
|
||
|
False: "no"},
|
||
|
},
|
||
|
"mob_area": {
|
||
|
"name": "proxemics",
|
||
|
"values":{
|
||
|
"5": "personal",
|
||
|
"100": "social",
|
||
|
"500": "public",}},
|
||
|
"mob_openspace": {
|
||
|
"name": "open space",
|
||
|
"values":{
|
||
|
True: "yes",
|
||
|
False: "no"}},
|
||
|
# "mob_technology": {},
|
||
|
"physical_interaction": {
|
||
|
"name": "physical contact",
|
||
|
"values": {
|
||
|
"touch": "haptics",
|
||
|
"close": "close-contact"}},
|
||
|
"contact": {},
|
||
|
"role": {},
|
||
|
"importance": {
|
||
|
"name": "focus",
|
||
|
"values": {
|
||
|
"2nd": "secondary"}},
|
||
|
"safety": {
|
||
|
"values":{
|
||
|
True: "yes",
|
||
|
False: "no"}},
|
||
|
}
|
||
|
|
||
|
|
||
|
csv_reader = csv.reader(content, dialect=csv.excel_tab)
|
||
|
keys = next(csv_reader)
|
||
|
values = {}
|
||
|
for key in keys:
|
||
|
if key not in values:
|
||
|
values[key] = {}
|
||
|
|
||
|
for row in csv_reader:
|
||
|
for i in range(len(keys)):
|
||
|
key = keys[i]
|
||
|
full_cell = row[i]
|
||
|
if full_cell == '0':
|
||
|
cells = [False]
|
||
|
elif full_cell == '1':
|
||
|
cells = [True]
|
||
|
else:
|
||
|
if ", " in full_cell:
|
||
|
cells = full_cell.split(', ')
|
||
|
else:
|
||
|
cells = [full_cell]
|
||
|
|
||
|
for cell in cells:
|
||
|
if cell not in values[key]:
|
||
|
values[key][cell] = 1
|
||
|
else:
|
||
|
values[key][cell] += 1
|
||
|
|
||
|
|
||
|
|
||
|
ax = init_graph()
|
||
|
for i, (column_name, column_label) in enumerate(reversed(list(column_labels.items()))):
|
||
|
add_graph_field(
|
||
|
ax,
|
||
|
i % 2,
|
||
|
column_name,
|
||
|
column_label,
|
||
|
*percentage_keys(values[column_name])
|
||
|
)
|
||
|
|
||
|
ax.set_xlabel("Percentage")
|
||
|
ax.set_title("Criteria")
|
||
|
plt.savefig("trululu.pdf")
|
||
|
|
||
|
|
||
|
for column_name in column_labels.keys():
|
||
|
print(column_labels[column_name].get("name", column_name))
|
||
|
for key, percentage in zip(*percentage_keys(values[column_name])):
|
||
|
key_label = column_labels[column_name].get("values", {}).get(key, key)
|
||
|
print(f"\t{key_label}\t{percentage}")
|
||
|
print()
|
||
|
|
||
|
|
||
|
def percentage_keys(values):
|
||
|
total = 0
|
||
|
sorted_keys = sorted(
|
||
|
values.keys(),
|
||
|
key=lambda key: -values[key]
|
||
|
)
|
||
|
for key, n in values.items():
|
||
|
total += n
|
||
|
|
||
|
return sorted_keys, [
|
||
|
round((values[key] * 100) / total)
|
||
|
for key in sorted_keys
|
||
|
]
|
||
|
|
||
|
def init_graph():
|
||
|
fig, ax = plt.subplots(figsize=(10,6))
|
||
|
return ax
|
||
|
|
||
|
def add_graph_field(ax, color_index, field, labels, values, percentages):
|
||
|
start = 0
|
||
|
|
||
|
category_colors = [
|
||
|
plt.colormaps['coolwarm'](np.linspace(0.15, 0.85, len(values))),
|
||
|
plt.colormaps['Spectral'](np.linspace(0.15, 0.85, len(values)))
|
||
|
][color_index]
|
||
|
|
||
|
for i, (value, percentage) in enumerate(zip(values, percentages)):
|
||
|
rects = ax.barh([labels.get("name", field)], [percentage], left=[start], label=value, height=0.8, color=category_colors[i])
|
||
|
|
||
|
start += percentage
|
||
|
|
||
|
ax.bar_label(rects, labels=[
|
||
|
labels.get("values", {}).get(value, value)
|
||
|
], label_type="center")
|
||
|
|
||
|
|
||
|
def main():
|
||
|
with open(filename) as fh:
|
||
|
scan_csv_list(fh.readlines())
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|