2016-04-07 4 views
1

Ich möchte die Spitzen einer Funktion zu visualisieren, und ich möchte Marker dafür haben über die Linie, die sie zugeordnet sind.MATLAB/Octave Plot Marker über der Linie und nicht auf der Linie

ich fabriziert ein Minimum Beispiel, wo ich die Spitzen bereits haben, ist die Frage, wie die Markierungen richtig sichtbar zu machen:

y = [0.1 0.3 10.0 1.0 0.5 0.1 24.0 0.6 0.1 0.2] 
x = (1:length(y)) 
plot(x,y); 

hold on; 

peaks = [3 7]; 
plot(x(peaks), y(peaks), 'v', 'MarkerSize', 24); 

print('-dpng', 'example.png', '-S640,480'); 

So, als Folge erscheinen die Markierungen auf der Linie wie folgt ausgerichtet: markers shown on the line

Das Ergebnis, das ich will durch vorsichtiges Einstellen eines Parameters OFFSET wie dies erreicht werden könnte:

plot(x(peaks), y(peaks)+OFFSET, 'v', 'MarkerSize', 24); 

Wie in der folgenden Abbildung gezeigt, funktioniert OFFSET=2.56 für das exportierte PNG, aber mit dem interaktiven Plot und dem Exportieren von Vektorgrafiken ist es wieder falsch.

markers above line, as is desired

Kann jemand einen Weg empfehlen, dieses Ergebnis zu erhalten, ohne manuell Versuch/Fehler zu tun zu haben?

Momentan verwende ich Octave mit gnuplot, um nach latex + tikz zu exportieren, und es wäre gut, wenn die Lösung dort funktionieren würde.

In meinem eigentlichen (komplizierteren) Anwendungsfall zeichne ich mehrere Zeilen hintereinander in die gleiche Figur, und die y-Grenzen ändern sich, so dass die Offsets nicht einfach berechnet werden können, da sich die Markergröße nicht ändert die y-Grenzen.

Edit: Zusätzlich verwende ich ein Semilogx-Plot, so dass Linien innerhalb des Diagramms in der X/Y-Achse Skalen würde verzerrt aussehen.

Antwort

1

Was ist mit dem Zeichnen der kleinen Dreiecke?

y = [0.1 0.3 10.0 1.0 0.5 0.1 24.0 0.6 0.1 0.2]; 
x = (1:length(y)); 
peaks = [3 7]; 
plot(x,y); 

hold on; line([peaks(1) peaks(1)+0.2], [y(x==peaks(1)) y(x==peaks(1))+1], 'color','b') 
hold on; line([peaks(1) peaks(1)-0.2], [y(x==peaks(1)) y(x==peaks(1))+1], 'color','b') 
hold on; line([peaks(1)+0.2 peaks(1)-0.2], [y(x==peaks(1))+1 y(x==peaks(1))+1], 'color','b') 

hold on; line([peaks(2) peaks(2)+0.2], [y(x==peaks(2)) y(x==peaks(2))+1], 'color','b') 
hold on; line([peaks(2) peaks(2)-0.2], [y(x==peaks(2)) y(x==peaks(2))+1], 'color','b') 
hold on; line([peaks(2)+0.2 peaks(2)-0.2], [y(x==peaks(2))+1 y(x==peaks(2))+1], 'color','b') 

Es kann ein Problem geben, wenn die y-Werte der Spitzen an anderen Stellen des Vektors vorhanden sind. Wenn dies der Fall ist, können Sie first oder andere passende Spezifikationen für die find-Funktion angeben.

+0

warst du ein bisschen schneller;) –

+0

ein kleines bisschen ... :) – Adiel

+0

Dies funktioniert in octave + gnuplot und ist schon hilfreich, aber jetzt ändert sich das Seitenverhältnis des Dreiecks je nach y und x Grenzen ändern. In meinem realen Anwendungsfall verwende ich sogar eine logarithmische Darstellung, so dass sie vollständig verzerrt wird. Irgendwelche anderen Ideen? ... EDIT: Ok, ich denke ich könnte auch den Marker exponentiell plotten lassen und je nach Achse skalieren, es wird nur ein wenig kompliziert ... – bluesceada

1

In Bezug auf den Matlab-Teil könnten Sie die Peak-Marker selbst zeichnen. Irgendwo entlang dieser Linien (Erweiterung Ihrer Beispiel):

y = [0.1 0.3 10.0 1.0 0.5 0.1 24.0 0.6 0.1 0.2] 
x = (1:length(y)) 
figure, plot(x,y); 
leglengthx=0.2; 
leglengthy=0.5; 
hold on; 

peaks = [3 7]; 
peaks_max=[10 24]; 

for ii=1:2 
    line([peaks(ii) peaks(ii)+leglengthx],[peaks_max(ii) peaks_max(ii)+leglengthy]); 
    line([peaks(ii) peaks(ii)-leglengthx],[peaks_max(ii) peaks_max(ii)+leglengthy]); 
    line([peaks(ii)-leglengthx peaks(ii)+leglengthx],[peaks_max(ii)+leglengthy peaks_max(ii)+leglengthy]); 
end 

plot(x(peaks), y(peaks), 'v', 'MarkerSize', 24); 

ich die Maxima der Peaks hinzugefügt haben, die kein Problem automatisch sein sollte, zu extrahieren und zu zwei Variablen, die die Dreiecksgröße des Markers zu steuern. Und dann zeichnet es nur drei Linien für jeden Gipfel.

Ich weiß nicht, wie dies zu Octave übersetzen wird.

+0

Nur als eine Anmerkung: peaks_max = y (Spitzen) – bluesceada

+0

@bluesceada wahr, danke –