2011-08-08 12 views
9

Często muszę wizualizować wiele zestawów danych jednocześnie, zwykle w ListPlot lub w jego towarzyszących logach. Ponieważ liczba zestawów danych jest zwykle większa niż liczba łatwo odróżnialnych stylów linii, a tworzenie dużych legend fabuły wciąż jest dość nieintuicyjne, wciąż szukam dobrego sposobu na opisywanie różnych linii/zestawów na moich wykresach. Etykietka jest fajna podczas pracy na ekranie, ale nie pomagają, jeśli muszę wyliczyć fabułę.Jak dodawać adnotacje do wielu zestawów danych w ListPotach

Ostatnio grałem około opcją Mesh aby wyliczyć swoje zbiory danych i znaleźć jakieś dziwne rzeczy

GraphicsGrid[Partition[Table[ListPlot[ 
[email protected] 
Table[{Sin[x], Cos[x], Tan[x], Cot[x]}, {x, 0.01, 10, 0.1}], 
PlotMarkers -> {"1", "2", "3", "4"}, Mesh -> i, Joined -> True, 
PlotLabel -> "Mesh\[Rule]" <> ToString[i], ImageSize -> 180], {i, 
1, 30}], 4]] 

Wynik wygląda to na moim komputerze (Windows 7 x64, Mathematica 8.0.1):

 Mesh = i, with i running from 1 to 30

Zabawne, bo Mesh-> 2, 8, i 10 wynik wygląda jakbym oczekiwał, reszta nie. Albo nie rozumiem opcji Mesh, albo ona mnie nie rozumie.

Oto moje pytania:

  1. jest Mesh w ListPLot podsłuch czy mogę używać go niesłusznie?
  2. Jak mogę przesunąć x-oczka punktów siatki kolejnych zestawów, aby uniknąć nadruku?
  3. Czy masz jakieś inne sugestie, jak opisać/wyliczyć wiele zestawów danych w działce?
+3

Problem wzajemnego oddziaływania pomiędzy 'Mesh' i' PlotMarkers' był w [to SO pytanie] (http://stackoverflow.com/questions/4789047/custom-intervals-of-markers- in-mathematica-plotmarkers/4790805 # 4790805). Zgłosiłem to do WRI w tym czasie, a wsparcie techniczne przekazało to grupie rozwojowej. Mam nadzieję, że zostanie to naprawione w następnym wydaniu. – Simon

+1

Jestem ciekawy, dlaczego niektóre opcje siatki działają, a wiele innych nie. –

+2

Jeśli chodzi o trzecie pytanie, możesz zajrzeć do wykresu, którego użyłem tutaj: http://stackoverflow.com/questions/5745298/how-do-i-access-the-stackoverflow-api-from-mathematica/5745783 # 5745783. Obejmuje to ręczne adnotacje (które mogą być wykonywane półautomatycznie). Czuję, że efekt końcowy jest wizualnie o wiele przyjemniejszy niż wiele innych metod. –

Odpowiedz

12

Możesz spróbować czegoś podobnego. Ustaw każdą linię w przycisku, który po kliknięciu identyfikuje się.

plot=Plot[{Sin[x],Cos[x]},{x,0,2*Pi}]; 
sinline=plot[[1,1,3,2]]; 
cosline=plot[[1,1,4,2]]; 
message=""; 
altplot=Append[plot,PlotLabel->Dynamic[message]]; 
altplot[[1,1,3,2]]=Button[sinline,message="Clicked on the Sin line"]; 
altplot[[1,1,4,2]]=Button[cosline,message="Clicked on the Cos line"]; 
altplot 

Jeśli dodać Podprogram można dostać miejsce, w którym kliknął i dodawania Jeśli stawka z odpowiednią etykietą umieszczoną na działce. Owiń fabułę dynamicznie, aby aktualizował się po każdym kliknięciu przycisku. To działa dobrze.

W odpowiedzi na komentarze, tu jest pełniejsza wersja:

plot = Plot[{Sin[x], Cos[x]}, {x, 0, 2*Pi}]; 
sinline = plot[[1, 1, 3, 2]]; 
cosline = plot[[1, 1, 4, 2]]; 
AddLabel[label_] := (AppendTo[plot[[1]], 
    Inset[Framed[label, Background -> White], pt]]; 
    (* Remove buttons for final plot *) 
    plainplot = plot; 
    plainplot[[1, 1, 3, 2]] = plainplot[[1, 1, 3, 2, 1]]; 
    plainplot[[1, 1, 4, 2]] = plainplot[[1, 1, 4, 2, 1]]); 
plot[[1, 1, 3, 2]] = Button[sinline, AddLabel["Sin"]]; 
plot[[1, 1, 4, 2]] = Button[cosline, AddLabel["Cos"]]; 
Dynamic[EventHandler[plot, 
    "MouseDown" :> (pt = MousePosition["Graphics"])]] 

Aby dodać kliknięcie etykiety na linii. Końcowy wykres z adnotacjami, ustawiony na "plainplot", można drukować i kopiować oraz nie zawiera on elementów dynamicznych.

[Później w ciągu dnia] Kolejna wersja, tym razem ogólna i oparta na początkowym wykresie. (W przypadku części używanych rozwiązania Mark McClure.) Dla różnych wykresów "ff" i "spec" można edytować zgodnie z potrzebami.

ff = {Sin, Cos, Tan, Cot}; 
spec = Range[0.1, 10, 0.1]; 
(* Plot functions separately to obtain line counts *) 
plots = Array[ListLinePlot[ff[[#]] /@ spec] &, [email protected]]; 
plots = DeleteCases[plots, Line[_?(Length[#] < 3 &)], Infinity]; 
numlines = Array[[email protected][plots[[#]], Line[_], Infinity] &, 
    [email protected]]; 
(* Plot functions together for annotation plot *) 
plot = ListLinePlot[#@spec & /@ ff]; 
plot = DeleteCases[plot, Line[_?(Length[#] < 3 &)], Infinity]; 
lbl = [email protected][ConstantArray[[email protected][[#]], 
     numlines[[#]]] &, [email protected]]; 
(* Line positions to substitute with buttons *) 
linepos = Position[plot, Line, Infinity]; 
Clear[line]; 
(* Copy all the lines to line[n] *) 
Array[(line[#] = plot[[Sequence @@ [email protected][[#]]]]) &, 
    [email protected]]; 
(* Button function *) 
AddLabel[label_] := (AppendTo[plot[[1]], 
    Inset[Framed[label, Background -> White], pt]]; 
    (* Remove buttons for final plain plot *) 
    plainplot = plot; 
    bpos = Position[plainplot, Button, Infinity]; 
    Array[(plainplot[[Sequence @@ [email protected][[#]]]] = 
     plainplot[[Sequence @@ Append[[email protected][[#]], 1]]]) &, 
    [email protected]]); 
(* Substitute all the lines with line buttons *) 
Array[(plot[[Sequence @@ [email protected][[#]]]] = Button[line[#], 
     AddLabel[lbl[[#]]]]) &, [email protected]]; 
Dynamic[EventHandler[plot, 
    "MouseDown" :> (pt = MousePosition["Graphics"])]] 

Oto jak to wygląda. Po adnotacji można znaleźć zwykły obiekt graficzny ustawiony na zmienną 'plainplot'.

Annotated Chart

+2

Bardzo ciekawy pomysł na prezentację! Jest to fajna alternatywa dla podpowiedzi (szczególnie, jeśli linia zostanie podświetlona w jakiś sposób, na przykład zostanie wytłuszczona - i nie musimy jej klikać, wystarczy na nią położyć mysz!). Dziękuję Ci. +1 –

+0

Bardzo fajny pomysł, jednak jest podobny do etykiety narzędziowej, która wydaje się być bezużyteczna, jeśli potrzebujesz wydrukować fabułę. Jednak prezentacja jest fajna. –

+3

@ Markus - Dodałem pełniejszy przykład, który pokazuje, że etykiety przyklejają się po umieszczeniu, więc wydruk z adnotacjami można wydrukować. –

8

Jednym ze sposobów jest generowanie wykresów osobno, a następnie wyświetlanie ich razem. To daje kod, który jest bardziej podobny do twojego, niż inny post, ponieważ wydaje się, że PlotMarkers gra w sposób, jakiego oczekujemy, gdy mamy do czynienia z jednym zbiorem danych. Możemy uzyskać takie samo zabarwienie przy użyciu ColorData z PlotStyle. Oto wynik:

ff = {Sin, Cos, Tan, Cot}; 
plots = Table[ListLinePlot[ff[[i]] /@ Range[0.1, 10, 0.1], 
    PlotStyle -> {ColorData[1, i]}, 
    PlotMarkers -> i, Mesh -> 22], {i, 1, Length[ff]}]; 
(* Delete the spurious asymptote looking thingies. *) 
plots = DeleteCases[plots, Line[ll_?(Length[#] < 4 &)], Infinity]; 
Show[plots, PlotRange -> {-4, 4}] 

enter image description here

+0

+1, jest to metoda, której używam, ponieważ czasami trzeba śledzić kilka dodatkowych wymiarów za pomocą symboli i kolorów, a nic nie działa tak dobrze. – rcollyer

+0

Byłem świadomy, że rozdzielenie powyższego przykładu na osobne działki jest obejściem - może to jest droga. –

4

Idziesz do kreślenia krzywych obliczalne lub rzeczywiste dane?

Jeśli są to krzywe obliczeniowe, zwykle używa się plot legend (key). Można użyć różnych wzorów i grubości, aby rozróżnić linie na drukarce w skali szarości. Istnieje wiele przykładów w dokumentacji PlotLegends.

Jeśli są to prawdziwe dane, to zwykle dane są wystarczająco rzadkie, aby można było użyć PlotMarkers dla rzeczywistych punktów danych (tj. Nie określaj Mesh). Możesz użyć automatycznego PlotMarkers lub użyć niestandardowych PlotMarkers, w tym znaczników BoxWhisker, aby wskazać różne niepewności.

+1

To rzeczywiście byłby standardowy sposób robienia tego. Jednak pakiet PlotLegend jest poważnie wadliwy (zobacz http://stackoverflow.com/questions/3463437/plotting-legends-in-mathematica/3533152#3533152), a ponadto, mam wrażenie, że ma problemy estetyczne. –

+0

@Sjoerd: Nie zauważyłem tego pytania. Sposób, w jaki 'PlotLegend' przeskalowuje' fabułę 'nie jest dobry ... – Simon

Powiązane problemy