Ich schreibe ein bisschen Code, um ein Balkendiagramm (oder ein Liniendiagramm) in unserer Software anzuzeigen. Alles läuft gut. Das, was mich verblüfft hat, ist die Beschriftung der Y-Achse.
Der Anrufer kann mir sagen, wie fein er die Y-Skala beschriften möchte, aber ich scheine genau zu wissen, was er auf "attraktive" Weise beschriften soll. Ich kann "attraktiv" nicht beschreiben und Sie wahrscheinlich auch nicht, aber wir wissen es, wenn wir es sehen, oder?
Wenn also die Datenpunkte sind:
15, 234, 140, 65, 90
Und der Benutzer fragt nach 10 Etiketten auf der Y-Achse. Ein bisschen Finagling mit Papier und Bleistift ergibt:
0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250
Es gibt also 10 (ohne 0), der letzte geht knapp über den höchsten Wert hinaus (234 <250) und es ist ein "schönes" Inkrement von jeweils 25. Wenn sie nach 8 Etiketten gefragt hätten, hätte ein Inkrement von 30 gut ausgesehen:
0, 30, 60, 90, 120, 150, 180, 210, 240
Neun wäre schwierig gewesen. Vielleicht habe ich nur 8 oder 10 verwendet und es nah genug genannt, wäre in Ordnung. Und was tun, wenn einige Punkte negativ sind?
Ich kann sehen, dass Excel dieses Problem gut angeht.
Kennt jemand einen Allzweckalgorithmus (selbst Brute Force ist in Ordnung), um dies zu lösen? Ich muss es nicht schnell machen, aber es sollte schön aussehen.
Antworten:
Vor langer Zeit habe ich ein Grafikmodul geschrieben, das dies gut abdeckt. Wenn Sie in die graue Masse graben, erhalten Sie Folgendes:
Nehmen wir Ihr Beispiel:
Der Bereich ist also = 0,25,50, ..., 225,250
Sie können den schönen Tick-Bereich mit den folgenden Schritten erhalten:
In diesem Fall wird 21,9 durch 10 ^ 2 geteilt, um 0,219 zu erhalten. Dies ist <= 0,25, also haben wir jetzt 0,25. Multipliziert mit 10 ^ 2 ergibt dies 25.
Schauen wir uns das gleiche Beispiel mit 8 Ticks an:
Welche geben das gewünschte Ergebnis ;-).
------ Hinzugefügt von KD ------
Hier ist Code, der diesen Algorithmus ohne Verwendung von Nachschlagetabellen usw. erreicht:
Im Allgemeinen enthält die Anzahl der Ticks das untere Tick, sodass die tatsächlichen Segmente der y-Achse eins weniger sind als die Anzahl der Ticks.
quelle
Hier ist ein PHP-Beispiel, das ich verwende. Diese Funktion gibt ein Array hübscher Y-Achsenwerte zurück, die die übergebenen minimalen und maximalen Y-Werte umfassen. Natürlich kann diese Routine auch für X-Achsenwerte verwendet werden.
Sie können "vorschlagen", wie viele Ticks Sie möchten, aber die Routine gibt zurück, was gut aussieht. Ich habe einige Beispieldaten hinzugefügt und die Ergebnisse für diese gezeigt.
Ergebnisausgabe aus Beispieldaten
quelle
Versuchen Sie diesen Code. Ich habe es in einigen Diagrammszenarien verwendet und es funktioniert gut. Es ist auch ziemlich schnell.
quelle
Klingt so, als würde der Anrufer Ihnen nicht die gewünschten Bereiche mitteilen.
Sie können also die Endpunkte so lange ändern, bis Sie sie durch Ihre Etikettenanzahl gut teilbar machen.
Definieren wir "schön". Ich würde nett anrufen, wenn die Etiketten von sind:
Finden Sie das Maximum und das Minimum Ihrer Datenreihen. Nennen wir diese Punkte:
Jetzt müssen Sie nur noch 3 Werte finden:
das passt zur Gleichung:
Es gibt wahrscheinlich viele Lösungen, wählen Sie einfach eine aus. Ich wette, Sie können die meiste Zeit einstellen
Probieren Sie einfach eine andere Ganzzahl aus
bis der Offset "schön" ist
quelle
Ich kämpfe immer noch damit :)
Die ursprüngliche Gamecat-Antwort scheint die meiste Zeit zu funktionieren, aber versuchen Sie, beispielsweise "3 Ticks" als Anzahl der erforderlichen Ticks einzugeben (für die gleichen Datenwerte 15, 234, 140, 65, 90) scheint einen Tick-Bereich von 73 zu ergeben, der nach Division durch 10 ^ 2 0,73 ergibt, was 0,75 entspricht, was einen 'schönen' Tick-Bereich von 75 ergibt.
Berechnen Sie dann die Obergrenze: 75 * rund (1 + 234/75) = 300
und die Untergrenze: 75 * rund (15/75) = 0
Aber klar, wenn Sie bei 0 beginnen und in Schritten von 75 bis zur Obergrenze von 300 fortfahren, erhalten Sie 0,75,150,225,300 .... was zweifellos nützlich ist, aber es sind 4 Ticks (ohne 0), nicht die 3 Ticks erforderlich.
Nur frustrierend, dass es nicht 100% der Zeit funktioniert ... was natürlich irgendwo auf meinen Fehler zurückzuführen sein könnte!
quelle
Die Antwort von Toon Krijthe funktioniert die meiste Zeit. Aber manchmal wird es eine übermäßige Anzahl von Zecken produzieren. Es wird auch nicht mit negativen Zahlen funktionieren. Die allgemeine Herangehensweise an das Problem ist in Ordnung, aber es gibt einen besseren Weg, um damit umzugehen. Der Algorithmus, den Sie verwenden möchten, hängt davon ab, was Sie wirklich erhalten möchten. Im Folgenden präsentiere ich Ihnen meinen Code, den ich in meiner JS Ploting-Bibliothek verwendet habe. Ich habe es getestet und es funktioniert immer (hoffentlich;)). Hier sind die wichtigsten Schritte:
Lasst uns beginnen. Zuerst die Grundberechnungen
Ich runde Minimal- und Maximalwerte, um 100% sicher zu sein, dass mein Plot alle Daten abdeckt. Es ist auch sehr wichtig, den Boden log10 des Bereichs zu bestimmen, ob er negativ ist oder nicht, und 1 später abzuziehen. Andernfalls funktioniert Ihr Algorithmus nicht für Zahlen, die kleiner als eins sind.
Ich benutze "gut aussehende Zecken", um Zecken wie 7, 13, 17 usw. zu vermeiden. Die Methode, die ich hier verwende, ist ziemlich einfach. Es ist auch schön, bei Bedarf ZeroTick zu haben. Die Handlung sieht auf diese Weise viel professioneller aus. Sie finden alle Methoden am Ende dieser Antwort.
Jetzt müssen Sie die oberen und unteren Grenzen berechnen. Dies ist mit null Tick sehr einfach, erfordert aber in anderen Fällen etwas mehr Aufwand. Warum? Weil wir die Handlung innerhalb der oberen und unteren Grenze schön zentrieren wollen. Schauen Sie sich meinen Code an. Einige der Variablen werden außerhalb dieses Bereichs definiert, andere sind Eigenschaften eines Objekts, in dem der gesamte dargestellte Code gespeichert ist.
Und hier sind Methoden, die ich zuvor erwähnt habe, die Sie selbst schreiben können, aber Sie können auch meine verwenden
Es gibt nur noch eine Sache, die hier nicht enthalten ist. Dies ist die "gut aussehende Grenze". Dies sind Untergrenzen, die Zahlen sind, die den Zahlen in "gut aussehenden Zecken" ähnlich sind. Zum Beispiel ist es besser, wenn die Untergrenze bei 5 mit der Zeckengröße 5 beginnt, als wenn ein Diagramm bei 6 mit der gleichen Zeckengröße beginnt. Aber das habe ich dir überlassen.
Ich hoffe es hilft. Prost!
quelle
Dies funktioniert wie ein Zauber, wenn Sie 10 Schritte + Null wollen
quelle
Konvertierte diese Antwort als Swift 4
quelle
Für alle, die dies in ES5 Javascript brauchen, ein bisschen gerungen haben, aber hier ist es:
Basierend auf der hervorragenden Antwort von Toon Krijtje.
quelle
Diese Lösung basiert auf einem Java-Beispiel, das ich gefunden habe.
quelle
Danke für die Frage und Antwort, sehr hilfreich. Gamecat, ich frage mich, wie Sie bestimmen, auf welchen Tick-Bereich gerundet werden soll.
Um dies algorithmisch zu tun, müsste man dem obigen Algorithmus Logik hinzufügen, um diese Skala für größere Zahlen gut zu machen? Wenn beispielsweise bei 10 Ticks der Bereich 3346 beträgt, ergibt sich ein Tick-Bereich von 334,6, und eine Rundung auf die nächsten 10 ergibt 340, wenn 350 wahrscheinlich besser ist.
Was denken Sie?
quelle
Basierend auf dem Algorithmus von @ Gamecat habe ich die folgende Hilfsklasse erstellt
quelle
Die obigen Algorithmen berücksichtigen nicht den Fall, wenn der Bereich zwischen Min- und Max-Wert zu klein ist. Und was ist, wenn diese Werte viel höher als Null sind? Dann haben wir die Möglichkeit, die y-Achse mit einem Wert über Null zu starten. Um zu vermeiden, dass sich unsere Linie vollständig auf der Ober- oder Unterseite des Diagramms befindet, müssen wir ihr etwas "Luft zum Atmen" geben.
Um diese Fälle abzudecken, habe ich (auf PHP) den obigen Code geschrieben:
quelle