1 Punkte von GN⁺ 2024-06-28 | 1 Kommentare | Auf WhatsApp teilen
  • eplot ist ein Paket, um direkt in Emacs einfache Diagramme aus numerischen Daten zu zeichnen; entstanden ist es aus den Grenzen von chart.el und der Kombination aus Org/Gnuplot bei Achsenbeschriftung und Bedienbarkeit
  • Die größte Herausforderung sind die Y-Achsen-Ticks: gut lesbare Zahlen aus der 1-2-5-Reihe sowie extreme Skalen und Zeitintervalle müssen natürlich behandelt werden
  • Erfahrungen mit einer bestehenden PHP-Chart-Bibliothek wurden nach Emacs Lisp übertragen; umgesetzt wurden Darstellungen wie SVG-basierte Gradients und Dark Mode, während einige Effekte, die pixelgenaue Verarbeitung erfordern, weggelassen wurden
  • Führt man in einem Buffer mit vielen Zahlen M-x eplot aus, öffnet sich ein Diagramm-Buffer; über Headers und C-c C-c lassen sich Einstellungen schnell ändern und das Ergebnis prüfen
  • Der Code ist auf GitHub veröffentlicht, ist aber Work in Progress, der innerhalb einer Woche stark testfallorientiert geschrieben wurde; Aufräumen der Codepfade und bessere Lesbarkeit stehen noch aus

Warum Diagramme direkt in Emacs zeichnen?

  • Auf der langen Suche nach einer einfachen Möglichkeit, unkomplizierte Plots zu erstellen, wurde beim Schreiben eines Artikels über Filmbewertungen das in Emacs enthaltene chart.el ausprobiert
  • chart.el ist zwar in Emacs enthalten, stammt aber ursprünglich aus einem Testwerkzeug für eieio; der Einsatzbereich ist daher begrenzt
  • Das Nötige ließ sich größtenteils erledigen, aber insbesondere die Darstellung der Y-Achse war unbefriedigend

Achsen-Ticks bestimmen die Qualität eines Diagramms

  • Schlechte Achsendarstellungen fallen sofort ins Auge; sie natürlich wirken zu lassen, erfordert jedoch den sorgfältigen Umgang mit vielen Grenzfällen
  • Auch Google Finance verwendete früher eine unnatürliche Achse, bei der der größte Wert als oberster Tick der Y-Achse gesetzt und Richtung Ursprung Linien in gleichen Abständen ergänzt wurden
    • Solche Diagramme gab es der Erinnerung nach etwa bis 2021
    • Später wurde die gesamte Site neu implementiert und erhielt bessere Achsen
  • Um 1997 wurde bei einer Aktienbrokerfirma bereits eine Chart-Bibliothek implementiert
  • Das Problem der Achsen-Ticks ist weniger ein schwieriges Mathematikproblem als vielmehr die sorgfältige Auswahl gut lesbarer Zahlen und Ausnahmebereiche
    • Gut lesbare Zahlen sind meist verschiedene Skalen von 1, 2, 5
    • In Aktiencharts können auch Bereiche wie $0.00001 bis $0.00002 oder 1e9 bis 1e10 vorkommen
    • Bei Zeitachsen müssen Jahre, Halbjahre, Quartale, Monate, Wochen und sogar die Aufteilung von Monaten in Wochen berücksichtigt werden

Wo vorhandene Werkzeuge schwer direkt nutzbar sind

  • Die frühere PHP-Chart-Bibliothek ist praktisch, um Ergebnisse auf einem Webserver zu erzeugen, passt aber nicht dazu, innerhalb von Emacs mit Zahlen zu experimentieren
  • Wie die Beliebtheit von Excel und Jupyter Notebook zeigt, ist der Prozess wichtig, Daten interaktiv anzupassen und sich so dem gewünschten Diagramm zu nähern
  • Auch Org bietet Plot-Funktionen, doch Org plot verwendet Gnuplot als Backend
  • Gnuplot ist im Allgemeinen brauchbar, kann aber aufwendig werden, wenn man Standardwerte ändern will, etwa das Zahlenformat der Y-Achse in Beispielen

Implementierung und Darstellungsfunktionen von eplot

  • Da der Name chart bereits verwendet wird, wurde für das neue Paket der Name eplot gewählt
  • Es war nicht geplant, alle Funktionen der bestehenden PHP-Bibliothek zu übertragen, doch nach Beginn der Implementierung wurde der Großteil neu gebaut
  • Die neue Version enthält auch Funktionen wie Dark Mode
  • Die Gradients der PHP-Bibliothek waren handgeschrieben; der Erinnerung nach waren auch Dinge wie GIF-Colormap-Ressourcen enthalten
  • Die Emacs-Lisp-Version verwendet SVG
    • Da SVG Gradients unterstützt, wird durch die Kombination von Polygonen und Gradients ein ähnlicher Effekt erzielt
    • Damit lassen sich Ergebnisse erzielen, die dem PHP-Original ähneln
  • Ein anderer ungewöhnlicher Gradient wurde nicht implementiert
    • Er würde eine Umsetzung auf Pixel- oder zumindest Linienebene erfordern und ist daher schwierig
    • Da dafür möglicherweise mathematische Berechnungen nötig wären, wurde er weggelassen

Nutzungsablauf und Konfiguration

  • Führt man in einem Buffer mit vielen Zahlen M-x eplot aus, wird das Diagramm in einem separaten Buffer angezeigt
  • Um das Diagramm in die gewünschte Form zu bringen, wurde das Konzept der Headers eingeführt
  • Die meisten nützlichen Optionen lassen sich über Headers steuern
    • Fügt man Headers hinzu und drückt C-c C-c, sieht man das Ergebnis sofort
    • Dafür gibt es auch einen eplot mode, der den Ablauf erleichtert
  • Einfache Beispiele werden als klein dargestellte Diagrammformen angeboten; auch die meisten Varianten aus dem ersten Bild des Artikels wurden über Headers erzeugt

Veröffentlichungsstand und verbleibende Arbeiten

  • Eine README.md dokumentiert verschiedene Möglichkeiten
  • Der Code ist auf Microsoft Github veröffentlicht
  • Der aktuelle Zustand ist weiterhin Work in Progress
  • Grundsätzlich könnte es bereits einigermaßen nützlich sein, doch da der Code innerhalb einer Woche fortlaufend geändert und geschrieben wurde, lässt sich seine Stabilität schwer einschätzen
  • Der Code wurde testfallweise auf ineffiziente Weise geschrieben und muss aufgeräumt werden
    • Mehrere Codepfade müssen zusammengeführt werden
    • Die Lesbarkeit des Codes muss verbessert werden
  • Vorerst wurde der aktuelle Stand gepusht, um eine Pause einzulegen; tatsächliche Nutzer sollten noch vorsichtig sein

1 Kommentare

 
GN⁺ 2024-06-28
Meinungen auf Hacker News
  • Sauber! Die Art, wie der Gradient eingebaut wurde, ist einfach und zugleich clever.
    Da ich dieses Feld mag, noch ein allgemeiner Rat: Als ich früher bei Our World in Data mit Max Roser und Hannah Ritchie als Engineer an der Grapher-Bibliothek (https://github.com/owid/owid-grapher) gearbeitet habe, habe ich viel darüber gelernt, wie man gute Diagramme erstellt.
    Wenn man sich die Beispiele ansieht, sollte man Titel, Untertitel und Bildunterschriften nicht vernachlässigen. Da es bereits einen „einfachen Header“ gibt, dürfte sich das leicht gut einbauen lassen, und ein paar kurze Formulierungen machen einen großen Unterschied. Ich empfehle auch Cole Nussbaumer Knaflics „Storytelling with Data“.
    Wenn das weiterentwickelt wird, wird man irgendwann wahrscheinlich auch eine Datenfluss-Bibliothek und eine DSL einbauen wollen. Hadley Wickhams dplyr in R war das Beste, und auch in meinem Tool Ohayo sowie in der CoreTable-Bibliothek von OWID Grapher (https://github.com/owid/owid-grapher/tree/master/packages/%4...) habe ich mich an diesem Ansatz orientiert. Jeffrey Heers relativ neue Bibliothek Arquero (https://idl.uw.edu/arquero/) geht in eine ähnliche Richtung.
    In letzter Zeit schaue ich mir Mike Bostocks neues Tool Plot (https://observablehq.com/plot/) an; ich habe es bisher zwar erst ein, zwei Tage benutzt, aber es wirkt vielversprechend. Ich nutze Emacs derzeit nicht, hoffe aber, dass das oben Gesagte hilfreich ist.
  • Deshalb konnte ich also den jüngsten Artikel „10 % der Emacs-Bugs behoben“ nicht finden. Offenbar war er damit beschäftigt, das hier zu bauen. Cool, ein echter Emacs-Profi.
  • Sieht gut aus! Wenn man für die Diagrammkonfiguration Emacs’ Funktion für datei- und verzeichnislokale Variablen nutzt, könnte das eine flexiblere User Experience ergeben.
    Zum Beispiel könnte man gerade eine Datendatei erzeugen und sie vor dem Zeichnen des Diagramms nicht manuell ändern wollen, oder man möchte in einem Verzeichnis mit großen Datendateien die Dateien jeweils bei Bedarf plotten, ohne jeder Datei von Hand Header hinzuzufügen.
  • Beim Zeichnen von Graphen in org mode kann man auch Python und matplotlib verwenden. Es geht nicht nur mit Gnuplot.
    • Matplotlib hat bereits eine ziemlich unbequeme API, und ich glaube nicht, dass ein elisp-Wrapper darüber daraus etwas besonders Angenehmes macht.
      Wie im Originalbeitrag gesagt, könnte es gut sein, dass am Ende mehr Code nötig ist, als wenn man es direkt implementiert.
    • Was mich an matplotlib und gnuplot immer stört, ist, dass es buchstäblich für alles einen eigenen Befehl oder Funktionsaufruf zu geben scheint.
      Wenn man die Größe der Ticks der dritten Ebene auf der Y-Achse ändern will, ruft man etwas wie set_third_level_y_ticks() auf. Das ist nicht unbedingt schlecht, und vielleicht geht es gar nicht anders, aber es wirkt, als wäre alles sonderbehandelt, wodurch sich die Orthogonalität geringer anfühlt.
    • Es gibt auch ESS (Emacs Speaks Statistics). Das bindet R/Julia stark in org-mode ein, sodass man Dinge wie ggplot2 oder makie verwenden kann.
      Trotzdem respektiere ich den Versuch, etwas in reinem elisp zu bauen.
    • Man kann auch R und dessen Grafikbibliotheken verwenden.
  • Das ist echtes Hacking. Besonders der Gradient gefällt mir.
    Dass diese Plots SVGs sind und sich daher in LaTeX oder Webbrowser übernehmen lassen, ist ebenfalls ein großer Pluspunkt. Ersteres macht sie zu einem ziemlich starken Kandidaten, wenn man Plots erstellen muss, die in Paper eingefügt werden sollen. Gute Arbeit.
  • Es ist das erste Mal, dass ich die zwei Wörter „Microsoft Github“ so unverblümt nebeneinander sehe, und auch wenn es schon seit Jahren wahr ist, fühlt es sich unangenehm an.
    • Ich verstehe immer noch nicht, warum so viele freie und Open-Source-Projekte diese Plattform nutzen. GitHub war sehr erfolgreich darin, dafür zu sorgen, dass die Leute das Präfix Microsoft nicht sehen.
      Immerhin scheint Codeberg inzwischen unter freien und Open-Source-Projekten endlich etwas an Fahrt zu gewinnen.
    • Deshalb scheint GitHub immer noch so tun zu wollen, als wäre es das unabhängige Startup von früher. Viele unabhängige Entwickler empfinden ähnlich und neigen eher zu Werten rund um Softwarefreiheit als zu Shareholder Value oder Big-Tech-Kapitalismus.
      Ich habe gerade die Startseite von github.com geöffnet und per Ctrl-F nach „Microsoft“ gesucht: 0 Treffer.
    • Ich hatte genau dieselbe Reaktion. Ich hoffe, dass sie irgendwann nicht zu MS GitHub rebranden.