Grafische Veranschaulichung des Preisleistungsverhältnis

Mir war langweilig und da hab ich mal einen kurzen Python-Code geschrieben, um Grafiken zu erzeugen, die das Preis-Leistungs-Verhältnis von Produkten im Tasting darstellen:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

### Load data
results = pd.read_csv('tastingresults.csv', sep=';', decimal=',')
print(results)

### Prepare figure
fig = plt.figure()
axes = fig.add_subplot(1,1,1)
axes.set_xlabel('Preis (€/l)', fontsize=20)
axes.set_ylabel('Durchschnittliche Bewertung', fontsize=20)
# Figure style
for axis in ['top','bottom','left','right']:
    axes.spines[axis].set_linewidth(2)
axes.minorticks_on()
axes.tick_params(which='major', width=2, pad=10, length=10, labelsize=20)
axes.tick_params(which='minor', width=2, pad=10, length=5)
# Figure dimensions
axes.set_xlim(left=0, right=80)
axes.set_ylim(bottom=0, top=10)
axes.xaxis.set_minor_locator(ticker.MultipleLocator(10))
axes.xaxis.set_major_locator(ticker.MultipleLocator(20))
axes.yaxis.set_minor_locator(ticker.MultipleLocator(1))
axes.yaxis.set_major_locator(ticker.MultipleLocator(2))

### Draw figure
axes.plot(results['Preis'],
          results['Bewertung'],
          'o',
          color='orange',
          markersize=12,
          markeredgewidth=1.5)
if 'Standardabweichung' in results:
    axes.errorbar(results['Preis'],
                  results['Bewertung'],
                  yerr=results['Standardabweichung'],
                  fmt='none',
                  ecolor='orange',
                  elinewidth=2,
                  capsize=0,
                  capthick=2)
for name, price, rating in zip(results['Produkt'],
                               results['Preis'],
                               results['Bewertung']):
    axes.text(price,
              rating + 0.025*(axes.get_ylim()[1] - axes.get_ylim()[0]),
              name,
              horizontalalignment='center',
              #verticalalignment='center',
              color='black',
              fontsize=13)

### Save figure
fig.tight_layout()
fig.savefig('preisleistung.png')

Das Resultat (für @Mixael’s Rye-Tasting) sieht dann etwa so aus:


Die Fehlerbalken stellen die Standardabweichung dar und sind ein Maß für die Streuung der Bewertungen.

Man könnte alternativ anstelle der Namen der Produkte auch nur die Nummer aus dem Tasting an den Datenpunkt schreiben. Das ist dann etwas übersichtlicher aber man muss mit einer Tabelle vergleichen.

Bei Produkten mit gleichem Preis habe ich mir erlaubt, diese um 0,10 € zu verschieben, um die Fehlerbalken unterscheiden zu können.

Um das Skript verwenden zu können, muss man die Daten als .csv-Datei Speichern in der folgenden Form:
image

Am Anfang vom Skript sollte man dann noch definieren, ob in der .csv-Datei ein Komma oder Semikolon als Trennzeichen verwendet wird, und ob man die Zahlen mit Komma oder Punkt schreibt.

Die Daten für die Standardabweichung sind optional.

Was haltet ihr von der Darstellung? Falls Interesse Besteht könnte ich das Skript auch dahin gehend erweitern, dass man die Daten von allen Testern einließt und Mittelwert und Standardabweichung automatisch berechnet werden.

4 „Gefällt mir“

Spontan könnte ich mir vorstellen die beiden Achsen zu vertauschen – vertikal der Preis und horizontal die Bewertung.

Kann man machen. Hier der direkte Vergleich:

Preise sollten natürlich pro Liter angegeben werden (hatte ich zunächst falsch gemacht).

Ich werde wahrscheinlich noch eine Option einbauen die Labels zu verschieben. Dann können die z.B. über oder unter den Datenpunkten sitzen.

Im Vergleich sind die horizontalen Fehlerbalken dann doch nicht so gut. Die ursprüngliche Version wirkt stimmiger … wobei ich mich gerade Frage ob man die Fehlerbalken wirklich braucht. Das es Schwankungen gibt sollte ja jedem Klar sein.

Die Balken veranschaulichen halt, wie polarisierend ein Produkt ist. Wild Turkey ist z.B. im Vergleich zu Jack Daniels sehr polarisierend. Deswegen habe ich für die Balken auch die „Standardabweichung“ gewählt und nicht die „Standardabweichung vom Mittelwert“. Letztere ist um die Wurzel der Teilnehmeranzahl kleiner und gibt an, wie präzise der Mittelwert bestimmt wurde. Mit zunehmender Menge an Teilnehmern bleibt die einfache „Standardabweichung“ gleich, während die „Standardabweichung vom Mittelwert“ kleiner und kleiner wird.

Ich finde die Information, die die Standardabweichung bietet schon sehr aufschlussreich. Wer sie nicht verarbeiten kann, darf sie aber gerne auch einfach ignorieren. :wink:

Verarbeiten kann ich sie schon. Ich finde die Balken im Diagramm nur grafisch nicht optimal umgesetzt. Es bringt ja letztendlich nichts wenn man alle Infos reinpackt aber sie sich nicht sauber entschlüsseln lassen. Ich wäre auch vorsichtig bei kleinen Tastings mehr als den Mittelwert anzugeben – ein Tester der aus der Reihe fällt kann dann schon einen sehr irreführenden Eindruck erwecken.

Wahrscheinlich muss man das mal mit ein paar Tastings durchspielen um zu sehen was funktioniert. Wenn die Ergebnisse enger und die Preisunterschiede geringer sind müsste man auf jeden Fall die Einteilung der Achsen ändern …

Ich hatte noch einen Fehler bei der Berechnung der Standardabweichung (hätte ich das mal ordentlich gemacht und nicht mit Excel …). Die Ergebnisse vom Rye-Tasting haben nämlich eigentlich vergleichsweise wenig zwischen den Testern fluktuiert. Hier die neuen Ergebnisse:


Ich kann bei Gelegenheit gerne mal ein paar andere Tastings in rein laden.

Ich verstehe, was du meinst. Das Problem beim Beschneiden von Achsen (so dass der Nullpunkt nicht mehr abgebildet wird), ist dass die Proportionen auf den ersten Blick nicht mehr korrekt dargestellt werden. Das ist ein beliebtes Mittel in der Datenmanipulation. Wenn ich z.B. erst bei 30 €/l anfinge, würden Wild Turkey und Jack Daniels noch viel günstiger ausschauen. Bei den Bewertungen ist das vielleicht etwas weniger kritisch.

Es gibt natürlich ein paar Tastings, wo die Darstellung nicht funktionieren wird, weil mehrere Proben vom selben Hersteller enthalten sind mit dem gleichen Preis (siehe z.B. 2011 Pisco).

Ich würde eher sagen das ist ein oft nötiges Mittel. Arbeitet man mit größeren Zahlen die nah zusammenliegen geht es gar nicht anders. Wenn man die Achsen klar und deutlich beschriftet ist das aber problemlos nachvollziehbar und meiner Meinung nach völlig legitim.

Dem Punkt widerspreche ich. (Abgesehen davon, dass ich nicht beurteilen möchte, ob Tester „richtig“ oder „falsch“ abgestimmt haben.) Stell dir vor von den 6 Testern hätte einer böswillig Rittenhouse mit nur 1 Punkt bewertet. Dann würde der Mittelwert von etwa 6 Punkten auf 5 Punkte sinken. Rittenhouse wäre nicht mehr das dritt-beste Produkt sondern das zweit-schlechteste. Die Standardabweichung würde sich aber verdoppeln. Das heißt ohne die Information aus der Standardabweichung würde man gar nicht sehen, wie kontrovers das Ergebnis für Rittenhouse wäre. Ich würde daher argumentieren, dass man gerade bei Ausreißern die Standardabweichung braucht um eine Idee zu bekommen, wie sehr man dem Mittelwert trauen kann.

Nur zum Verständnis: Ich sehe bei der Abweichung die minimalen und maximalen Bewertungen die Vergeben wurden plus den rechnerischen Mittelwert bzw. das Ergebnis des Tastings?

Oder kannst du das Rittenhouse-Beispiel mal in beiden Varianten simulieren?

Nein, du siehst den Mittelwert plus die Standardabweichung.

Standardabweichung = WURZEL(SUMME((BEWERTUNG - MITTELWERT)^2) / (TEILNEHMERANZAHL - 1))
Oder auch:
image
Wobei xi die Bewertung vom i-ten Teilnehmer ist, x-bar ist der Mittelwert und N die Anzahl der Teilnehmer.

Ich war in Mathe, trotz dessen dass meine Eltern Mathematiker sind, nie wirklich gut. :anguished:

Gute Sache! Der Code ist ja sogar kommentiert! :wink:

Ich finde die Darstellung mit vertikalen Balken gut, man tendiert beim Lesen von Diagrammen ja, nach dem obersten Wert zu schauen. Die Balken dürften für mein Empfinden aber etwas dezenter sein.
Abgeschnittene Achsen würde ich befürworten, da ja die Produkte miteinander verglichen werden sollen und der absolute Geldbetrag für diese Aussage eine weniger wichtige Rolle spielt.

Ich würde statt der Standardabweichung allerdings einen Interquartilsabstand (IQR, 75- minus 25-Perzentil) ins Rennen schicken, der ist robuster gegenüber Ausreißern und gibt die Streuung m.E. verlässlich wieder. Wenn man es perfekt machen wollen würde, dann box-plot ähnlich mit Whiskern und Ausreißern. Das ist aber sicher Overkill und keiner blickt mehr im Diagramm durch.

Hier ein Extrembeispiel, warum die StAbw. problematisch ist:
Bei Probe 1 stimmen alle mit „5“ ab, außer ein Tester, der gibt nur einen Punkt. Bei Probe 2 ist von 3 Punkten bis 6 Punkten alles dabei. Mit der Standardabweichung streut die erste Probe stärker, obwohl fast alle einer Meinung sind. Mit der IQR wird m.E. eine bessere Wiedergabe der Verteilung erreicht.

Tester Probe 1 Probe 2
1 5 3
2 5 4
3 5 5
4 5 6
5 5 5
6 5 4
7 5 3
8 1 6
Mean 4.5 4.5
Stabw 1.32 1.12
IQR 0 1.5

image

Vergleich die Balken einfach mal mit den Rohdaten aus dem Tasting. Dann bekommst du schon ungefähr eine Vorstellung, wie die Berechnung funktioniert. :slightly_smiling_face:

Zumindest ein bischen. :wink:

Meinst du farblich dezenter? Dünner würde ich sie auf jeden Fall nicht zeichnen wollen.

Die Grafiken sind eigentlich ausschließlich dazu gedacht das Preisleistungsverhältnis darzustellen. Wenn man ein Tasting hat, wo alle Proben nen Literpreis von 35-40 € haben, dann ist der Preisunterschied natürlich nicht mehr relevant. Dann würde ich die Bewertungen aber auch nicht gegen Preis pro Liter auftragen sondern einfach nur als Histogramm in der Reihenfolge der Durchschnittsbewertung (also so ähnlich wie wir das in der Vergangenheit auch schon hatten). Die Darstellung des Preisleistungsverhältnis soll auch eine Darstellung des Ranking nicht ersetzen sondern eine ergänzende Darstellung sein.

Das wirft jetzt eine interessante Frage auf. Und zwar: Sollen „Ausreißer“ für die Darstellung der Streuung der Ergebnisse ignoriert werden? Wenn wir von experimentellen Daten sprechen würden, bei denen Ausreißer zu erwarten sind, weil bei der Messung z.B. irgendetwas schief läuft und diese Daten damit nicht mehr repräsentativ sind, dann ist das sicher eine gute Methode. Ich finde es aber schwierig bei Tastings von „Ausreißern“ zu sprechen, weil halt doch jeder einen individuellen Geschmack hat. In der Vergangenheit wurde ja sogar häufiger hervorgehoben, wie viele Tester ein Produkt als bestes Produkt bewertet haben. Dazu würde ich gerne ein paar mehr Meinungen hören.
Eine kleineres Detail, das mir am Interquartilsabstand nicht gefällt, ist die Tatsache, dass er hier sehr diskret wäre, wenn alle Tester nur ganze Punkte vergeben.

So, ich habe jetzt für euch mal verschiedene Methoden zusammengestellt um die Verteilung der Bewertungen darzustellen. Als Grundlage habe ich die Pur-Bewertungen des Agricole-Tasting von 2011 her genommen. Die Produkte sind der Einfachheit halber nach ihrer mittleren Bewertung sortiert.

Standardabweichung: Stark abweichende Bewertungen werden stärker für die Verteilung gewichtet (siehe z.B. erstes Produkt).


Mittlereabweichung: Alle abweichenden Bewertungen werden gleich stark für die Verteilung gewichtet.

Interquartilsabstand: Die Verteilung erfasst etwa die mittlere Hälfte der Bewertungen.

Standardabweichung des Mittelwerts: Gibt die Unsicherheit an, mit der der Mittelwert bekannt ist

Die Balken in den ersten drei Darstellungen geben unterschiedliche Maße für die Verteilung der Bewertungen an. Nur die letzte Darstellung zeigt streng genommen einen „echten“ Fehlerbalken (für den Fehler vom Mittelwert).

Welche Balken repräsentieren eurer Meinung nach die Daten am besten? (Geht davon aus, dass ihr nur den Mittelwert + Balken seht. Bei welchen Balken würdet ihr am ehesten die zu Grunde liegenden Bewertungen erraten?)

Woher hast du denn deine Daten exportiert.
Und schau dir mal pathlib an. Ich zwinge mich die immer zu benutzen.

Jesus Touri! Das ist kein Skript, das automatisiert auf irgendeinem Server ausgeführt werden muss. :crazy_face: Die Datei liegt einfach im selben Verzeichnis. Das ganze soll möglichst einfacher verständlicher Code sein. Wenn ich anfangen würde das professioneller zu gestalten würde ich auch sicherlich die Style-Vorlagen für die Figures in einem separaten File global definieren.

Also, es sei denn natürlich du würdest gerne eine Web-Oberfläche schaffen, in die man seine Tastingergebnisse einpflegt und die anschließend direkt alle Auswertungen produziert. Die Arbeit will ich mir selber aber nicht antun. :wink:

Kommentare… *pah* :stuck_out_tongue:

Was spricht eigentlich dagegen die Darstellung genau so zu machen? Mit den Punktwolken im Hintergrund finde ich es geradezu perfekt. Bei den Balken würde ich eine der letzten beiden bevorzugen.