You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 2ffe2a8
Browse filesBrowse the repository at this point in the historyBrowse files
feat: extend the Plot board to the full data-visualization set
Add bar, countplot, histogram, pie, area, boxplot, heatmap, and
regression alongside scatter/line: a PlotKind union and per-kind payload
fields on PlotSpec, builtin call handling in the evaluator, and SVG
renderers for each chart on the Plot tab. New levels and a deep lesson
map each data question to the chart that answers it, with EN/DE/FA
copy.
Ein Diagramm ist eine **Entscheidung**, keine Deko. Deine Daten stellen schweigend eine Frage, und der Diagramm-*Typ* ist die Antwort. Bevor du ein Diagramm wählst, benenne die Frage. Die fünf Fragen, die du fast immer beantworten willst:
14
+
15
+
- **Zusammenhang** — „Wie hängen diese beiden Zahlen zusammen?" → scatter, line, area
16
+
- **Verteilung** — „Wie sind die Werte verteilt?" → histogram, boxplot
17
+
- **Zusammensetzung** — „Welchen Anteil hat jeder Teil am Ganzen?" → pie, area
18
+
- **Vergleich** — „Welche Kategorie ist größer?" → bar
19
+
- **Häufigkeit** — „Wie oft tritt etwas auf?" → countplot
20
+
- **Korrelation** — „Wie stark hängen viele Spalten zusammen?" → heatmap
21
+
22
+
Wähle das Diagramm, das zur Frage passt — dann erklärt es sich selbst.
23
+
24
+
## Intermediate
25
+
26
+
Die Entscheidungslandkarte. Jeder Pfeil heißt „diese Frage wird am besten von diesem Diagramm beantwortet":
27
+
28
+
- Zusammenhang ← **scatter / line / area / reg**
29
+
- Verteilung ← **hist / boxplot**
30
+
- Zusammensetzung ← **pie / area**
31
+
- Vergleich ← **bar**
32
+
- Häufigkeit ← **countplot**
33
+
- Korrelation ← **heatmap**
34
+
35
+
Einige schnelle Regeln, die die meisten Entscheidungen lösen:
36
+
37
+
- Zwei stetige Serien → **scatter** (sind sie korreliert?) oder **line** (ist eine geordnet, z. B. Zeit?).
38
+
- Eine Spalte roher Zahlen → **hist** (die Form) oder **boxplot** (Spanne + Ausreißer).
39
+
- Wenige Kategorien mit Werten → **bar**; wenn die Werte ein *Anteil eines Ganzen* sind → **pie**.
40
+
- Viele Kategorien, nur zählen → **countplot**.
41
+
- Ein Netz an Werten (Zeilen × Spalten) → **heatmap**.
42
+
43
+
## Advanced
44
+
45
+
**So baust du jedes ein.** Jedes Diagramm ist ein einziger Builtin, der ein Plot-Spec auf \`state.plots\` legt; der Plot-Tab rendert es. Hier die Argumentform jedes, mit einem ausführbaren Beispiel:
46
+
47
+
| Diagramm | Aufruf | Was jedes Argument ist |
48
+
|----------|--------|------------------------|
49
+
| scatter | \`scatter(xs, ys)\` | zwei ausgerichtete Zahlenlisten |
50
+
| line | \`line(xs, ys)\` | zwei ausgerichtete Zahlenlisten, in Reihenfolge |
51
+
| area | \`area(xs, ys)\` | zwei ausgerichtete Zahlenlisten, unter der Linie gefüllt |
52
+
| reg | \`reg(xs, ys)\` | zwei ausgerichtete Zahlenlisten; passt eine Linie |
53
+
| bar | \`bar(labels, values)\` | eine Label-Liste, eine Werte-Liste |
54
+
| countplot | \`countplot(labels)\` | eine Liste roher Labels (darf sich wiederholen) |
55
+
| hist | \`hist(values)\` | eine Liste roher Zahlen (automatisch gebinnt) |
56
+
| pie | \`pie(labels, values)\` | eine Label-Liste, eine Werte-Liste |
57
+
| boxplot | \`boxplot(values)\` | eine Liste roher Zahlen (Quartile berechnet) |
58
+
| heatmap | \`heatmap(rows, cols, matrix)\` | Zeilen-Labels, Spalten-Labels, eine Liste von Listen |
59
+
60
+
Zwei Formen merken: **ausgerichtete Zahlenlisten** (\`scatter(xs, ys)\`) für die 2D-Diagramme, und **Labels + Werte** (\`bar(labels, values)\`) für die Kategorie-Diagramme. Die Ausnahme ist \`heatmap\`, das eine *Matrix* nimmt — eine Liste von Listen, eine innere Liste pro Zeile.
61
+
62
+
\`\`\`python
63
+
xs = [1, 2, 3]
64
+
ys = [1, 4, 9]
65
+
scatter(xs, ys) # Zusammenhang
66
+
reg(xs, ys) # dieselben Daten, passte Linie
67
+
\`\`\`
68
+
69
+
## Expert
70
+
71
+
Die Datenform entscheidet, nicht dein Geschmack. Zwei Fallen, die in der Praxis auffallen:
72
+
73
+
- **bar braucht Labels und Werte; countplot nur rohe Labels.** Hast du sich wiederholende Kategorien, nutze \`countplot\` — es zählt selbst. Hast du schon je Kategorie einen Wert, nutze \`bar\`.
74
+
- **hist und boxplot nehmen rohe Werte, nicht vorgebinnte.** \`hist(data)\` und \`boxplot(data)\` nehmen eine flache Zahlenliste und binnen / berechnen Quartile selbst. Nicht vorab berechnen.
75
+
- **pie ist ein Anteil, bar ist eine Größe.** Summieren sich die Werte zu einem sinnvollen Ganzen, ist ein pie ehrlich; werden die Kategorien nur verglichen, ist es ein bar.
76
+
- **reg liefert den Fit.** \`reg(xs, ys)\` berechnet die kleinste-Quadrate-Steigung und den y-Abschnitt im Engine und zeichnet die Linie durch die Punkte — Diagramm und Mathematik stimmen überein.
77
+
78
+
## Master
79
+
80
+
Produktionsnamen, damit du den echten Code liest. Jedes Diagramm hier hat einen matplotlib / seaborn-Ableger:
81
+
82
+
- scatter → \`plt.scatter\` · line → \`plt.plot\` · area → \`plt.fill_between\`
83
+
- bar → \`plt.bar\` / \`sns.barplot\` · countplot → \`sns.countplot\`
- pie → \`plt.pie\` · heatmap → \`plt.imshow\` / \`sns.heatmap\`
86
+
- reg → \`sns.regplot\` / \`sns.lmplot\`
87
+
88
+
Wo es kaputtgeht: eine line setzt Reihenfolge voraus und lügt bei ungeordneten Kategorien. Ein pie mit mehr als ~6 kleinen Scheiben ist unlesbar. Eine heatmap braucht eine feste, geordnete Achse (meist normalisierte Werte), sonst codieren die Farben nichts. Die Memory-Model-Auszahlung bleibt: jedes Diagramm liest *dieselben* Listen, die du auf dem Canvas hältst — das Diagramm ist nur diese Objekte, gezeichnet.`,
89
+
},
11
90
levels: {
12
91
'shallow-copy-dict': {
13
92
name: 'Shallow Copy',
@@ -125,6 +204,78 @@ Beobachte das Brett: ein kleiner Punkt erscheint am Badge des Plot-Tabs, und ein
125
204
lesson: `Hier wird die Serie **berechnet**, nicht eingegeben. \`sq\` erzeugt jedes \`y\`, die \`ys\`-list wird aus diesen Ergebnissen gebaut, und \`line(xs, ys)\` verbindet die Punkte in der Reihenfolge.
126
205
127
206
Das ist die Form echten Plottings: Einige Daten transformieren, in abgestimmte Serien sammeln, dann zeichnen. Die Funktionsaufruf-Rahmen, die du in S5 gesehen hast, verrichten Arbeit, die das Diagramm füttert.`,
207
+
},
208
+
'plot-bar': {
209
+
name: 'Balkendiagramm',
210
+
brief: 'Baue `labels = ["A", "B", "C"]` und `vals = [3, 5, 2]`, dann `bar(labels, vals)`. Ein Balkendiagramm vergleicht einen Wert pro Kategorie mit den anderen.',
211
+
learning: ['`bar(labels, values)` vergleicht einen Wert pro Kategorie mit den anderen','Ein Balkendiagramm braucht zwei gleich lange lists: Labels und Werte'],
212
+
fieldNotes: ['matplotlib: `plt.bar(labels, vals)` / seaborn `sns.barplot`','Nutze bar für eine *Größe*; pie nur, wenn die Teile ein Ganzes ergeben'],
213
+
lesson: `Ein **Balkendiagramm** beantwortet „welche Kategorie ist größer?". Du gibst zwei gleich lange lists: \`labels\` (die Kategorien) und \`vals\` (je ein Wert). \`bar\` paart sie und zeichnet pro Kategorie einen senkrechten Balken, dessen Höhe der Wert setzt.
214
+
215
+
Das Memory-Modell ist wie scatter — zwei lists auf dem heap — aber das Diagramm liest sie *kategorisch positionell*, nicht als (x, y)-Koordinaten. Der Plot-Tab zeigt das Label unter jedem Balken und den Wert darüber.`,
216
+
},
217
+
'plot-countplot': {
218
+
name: 'Countplot',
219
+
brief: 'Baue `cats = ["red", "blue", "red"]`, dann `countplot(cats)`. Ein countplot zählt, wie oft jedes Label auftritt — keine separate Werte-list nötig.',
220
+
learning: ['`countplot(labels)` zählt eine rohe list sich wiederholender Labels','Zähl die Daten, tippe die Zählung nicht — das Diagramm macht es'],
221
+
fieldNotes: ['seaborn: `sns.countplot(labels)`','countplot ist die „Häufigkeit"-Frage; bar ist die „Größen vergleichen"-Frage'],
222
+
lesson: `Ein **countplot** beantwortet „wie oft tritt etwas auf?". Im Gegensatz zu \`bar\` nimmt er eine einzige list roher Labels, die **sich wiederholen** dürfen, und zählt sie selbst: \`red\` kommt zweimal vor, sein Balken ist 2.
223
+
224
+
Das ist die Häufigkeitsfrage. Du schreibst die Zählung nie — das Diagramm zählt die list. Schau den Plot-Tab: pro eindeutigem Wert ein Balken, die Höhe die Zählung.`,
225
+
},
226
+
'plot-hist': {
227
+
name: 'Histogramm',
228
+
brief: 'Baue eine list roher Zahlen, dann `hist(values)`. Ein Histogramm splittet die Zahlen in Klassen (Bins) und zeigt, wie viele in jede fallen — die Form einer Verteilung.',
229
+
learning: ['`hist(values)` binnt eine rohe list von Zahlen automatisch','Ein Histogramm zeigt die *Form* einer Verteilung, nicht Einzelwerte'],
230
+
fieldNotes: ['matplotlib `plt.hist` / seaborn `sns.histplot`','Die Binanzahl ändert das Bild — zu wenige verstecken Detail, zu viele werden Rauschen'],
231
+
lesson: `Ein **Histogramm** beantwortet „wie sind die Werte verteilt?". Du gibst eine flache list roher Zahlen; es splittet den Bereich in Klassen und zeichnet pro Klasse einen Balken für die *Anzahl* der fallenden Werte. Diese Silhouette ist die **Form der Verteilung** — ein Gipfel, wo Werte haufen, ein Schwanz, wo sie dünner werden.
232
+
233
+
Du gibst rohe Werte, keine vorab gemachten Zählungen. Das Engine binnt sie, damit Diagramm und Daten immer stimmen.`,
234
+
},
235
+
'plot-pie': {
236
+
name: 'Kuchendiagramm',
237
+
brief: 'Baue `parts = ["x", "y"]` und `vals = [70, 30]`, dann `pie(parts, vals)`. Ein Kuchendiagramm zeigt den Anteil jedes Teils am Ganzen.',
238
+
learning: ['`pie(labels, values)` zeigt den Anteil jedes Teils am Ganzen','Ein pie ist ein Anteilsdiagramm — nur für Teile-eines-Ganzen halten'],
239
+
fieldNotes: ['matplotlib: `plt.pie(vals, labels=parts)`','Ein pie mit vielen kleinen Scheiben ist ein bar im Verkleidung — wechsle zu bar'],
240
+
lesson: `Ein **Kuchendiagramm** beantwortet „welchen Anteil hat jeder Teil am Ganzen?". Es nutzt die gleiche Zwei-list-Form wie \`bar\` (Labels + Werte), zeichnet die Werte aber als **Scheiben eines Kreises**, damit das Auge Anteile vom Ganzen liest statt Größen.
241
+
242
+
Nutze einen pie, wenn die Werte zu etwas Sinnvollem summieren — Teile von 100 %, Stücke eines Budgets. Werden die Kategorien nur verglichen, ist bar das ehrlichere Diagramm.`,
243
+
},
244
+
'plot-area': {
245
+
name: 'Flächendiagramm',
246
+
brief: 'Baue `xs` und `ys`, dann `area(xs, ys)`. Ein Flächendiagramm ist eine Linie mit der darunter gefüllten Fläche — die kumulative Größe auf einer geordneten Achse.',
247
+
learning: ['`area(xs, ys)` füllt den Bereich unter einer Linie','Ein Flächendiagramm betont die sich aufsummierende *Größe* auf einer geordneten Achse'],
248
+
fieldNotes: ['matplotlib: `plt.fill_between(xs, ys)`','Gestapelte Flächendiagramme zeigen mehrere Serien, die zu einem Ganzen summieren'],
249
+
lesson: `Ein **Flächendiagramm** ist eine Linie mit dem Bereich **darunter gefüllt**. Es hat die gleichen zwei abgestimmten Zahlenlisten wie \`line\`, aber das Füllen macht die *Größe* jedes Punktes auf einen Blick lesbar — gut, wenn die y-Werte kumulativ sind oder du betonen willst, wie viel Fläche sich angesammelt hat.
250
+
251
+
Die x-Achse muss geordnet sein (Zeit, ein Index); das Füllen ist nur auf einer geordneten Achse sinnvoll.`,
252
+
},
253
+
'plot-boxplot': {
254
+
name: 'Boxplot',
255
+
brief: 'Baue eine list von Zahlen, dann `boxplot(values)`. Ein Boxplot komprimiert eine ganze Verteilung in eine Box (Quartile) mit Whiskers und Ausreißer-Punkten.',
256
+
learning: ['`boxplot(values)` fasst eine Verteilung in Quartile + Ausreißer zusammen','Die Box ist die mittlere Hälfte, die Linie der Median, die Punkte die Ausreißer'],
257
+
fieldNotes: ['matplotlib `plt.boxplot` / seaborn `sns.boxplot`','Der Klassiker: mehrere Boxplots nebeneinander, um Verteilungen zu vergleichen'],
258
+
lesson: `Ein **Boxplot** beantwortet „wie ist die Daten gestreut und wo sind die Ausreißer?" aus einer list roher Zahlen. Er berechnet die Quartile und zeichnet: eine **Box** vom 25. bis 75. Perzentil, eine Linie am **Median**, **Whiskers** bis zu den extremsten Werten im Bereich, und einen Punkt für jeden **Ausreißer** jenseits von 1,5× IQR.
259
+
260
+
Diese eine Box codiert die mittlere Hälfte der Daten, ihr Zentrum und die verdächtigen Werte an den Rändern — ein kompakter Ersatz für ein Histogramm, wenn Streuung und Extrema zählen.`,
261
+
},
262
+
'plot-heatmap': {
263
+
name: 'Heatmap',
264
+
brief: 'Baue `rows`, `cols` und eine `matrix` (list von lists), dann `heatmap(rows, cols, matrix)`. Eine heatmap färbt ein Netz an Werten, damit hohe/niedrige Werte auffallen.',
265
+
learning: ['`heatmap(rows, cols, matrix)` färbt ein Netz nach Wert','Die matrix ist eine list von lists — eine innere list pro Zeile'],
266
+
fieldNotes: ['matplotlib `plt.imshow` / seaborn `sns.heatmap`','Korrelations-Heatmaps nutzen dieselben Merkmale für Zeilen und Spalten'],
267
+
lesson: `Eine **heatmap** beantwortet „wo in diesem Netz sind die Werte hoch oder niedrig?". Sie ist das einzige Diagramm hier, das eine **Matrix** nimmt — eine *list von lists*, eine innere list pro Zeile — plus die Zeilen- und Spaltenlabels. Jede Zelle wird nach ihrem Wert eingefärbt, damit Gipfel und Täler sofort lesbar sind.
268
+
269
+
So werden Korrelationstabellen gezeichnet: Zeilen und Spalten sind dasselbe Merkmal-Set, und jede Zelle ist die Korrelation eines Paares. Starke Farbe = starke Beziehung.`,
270
+
},
271
+
'plot-regression': {
272
+
name: 'Regressionslinie',
273
+
brief: 'Baue zwei abgestimmte Serien `xs` und `ys`, dann `reg(xs, ys)`. Eine Regression passt die kleinste-Quadrate-Linie durch das scatter — der Trend, dem die Punkte folgen.',
274
+
learning: ['`reg(xs, ys)` passt die kleinste-Quadrate-Linie an ein scatter','Die Steigung ist die Änderungsrate des Trends; der y-Abschnitt sein Startwert'],
275
+
fieldNotes: ['seaborn: `sns.regplot` / `sns.lmplot`','Ein Linienfit geht von einer linearen Beziehung aus — prüfe zuerst das scatter'],
276
+
lesson: `Eine **Regression** beantwortet „gibt es einen geradlinigen Trend, und was ist er?". \`reg(xs, ys)\` berechnet die **kleinste-Quadrate**-Steigung und den y-Abschnitt im Engine und zeichnet die angepasste Linie durch deine scatter-Punkte — die Linie, die die Gesamtkarst zum Quadrat der Distanz zu den Punkten minimiert.
277
+
278
+
Das ist die Zusammenhangsfrage einen Schritt über \`scatter\`: Du siehst nicht nur, dass die Punkte einen Trend haben, du bekommst die *Gleichung* des Trends. Die Steigung ist die Änderungsrate, der y-Abschnitt der Punkt, wo die Linie die Achse kreuzt.`,
0 commit comments