Skip to main content

plotting - n-dimensional plot


I want to plot 6-dimensional data using parallel axes (https://en.wikipedia.org/wiki/Parallel_coordinates). The list looks like this:


    {{a1,b1,c1,d1,e1,f[a1,b1,c1,d1,e1]},{a2,b2,c2,d2,e2,f[a2,b2,c2,d2,e2]},{},...}

I need to draw six vertical axes with scales on them, connect the dots with lines, and color these lines according to the value of f[ai,bi,ci,di,ei], or the last coordinate.



A three dimensional example with two data would help me start, but I don't know how to do it.


Thank you.



Answer



Here's a start:


parallelPlot[dat_] := 
ListPlot[dat,
Prolog ->
Table[Line[{{i, Min[dat]}, {i, Max[dat]}}], {i,
Length[dat[[1]]]}],
PlotStyle ->

Table[Blend[{Red, Blue},
Rescale[dat[[i, -1]], {Min[dat[[All, -1]]], Max[dat[[All, -1]]]}
]], {i, Length[dat]}],
Joined -> True,
Axes -> False
]

Test:


parallelPlot[RandomInteger[{-5, 5}, {10, 6}]]


enter image description here


Things that one can easily add but I don't have time now:



  1. Rescale each coordinate separately.

  2. Ticks, labels, etc.

  3. Colorbar


======= Better function, that also rescales ========


The Rescale function is what you should use for rescaling. Let's keep the minimum and maximum of each dimensions in the variables mins and maxs, and thus


{mins, maxs} = Transpose[{Min[#], Max[#]} & /@ Transpose[data]];

rescaledData =
Transpose@
Table[Rescale[data[[All, i]], {mins[[i]], maxs[[i]]}], {i, Length@data[[1]]}];

We can then use mins and maxs to create tick labels at the bottom and top of each dimension. Here's the integrated code (I also added a Floor and Ceiling functions in the calculation of mins and maxs to make the bounds nicer):


parallelPlot[data_] := Block[{mins, maxs, rescaledData, n, ndim},
n = Length[data];
ndim = Length[data // First];
{mins, maxs} = Transpose[{Floor@Min[#], Ceiling@Max[#]} & /@ Transpose[data]];
rescaledData =

Transpose@
Table[Rescale[data[[All, i]], {mins[[i]], maxs[[i]]}], {i, ndim}];
ListPlot[rescaledData,
Prolog -> Table[Line[{{i, 0}, {i, 1}}], {i, ndim}],
PlotStyle -> Table[Blend[{Red, Blue}, rescaledData[[i, -1]]], {i, n}],
Epilog -> {
Table[Text[mins[[i]] // ToString, {i, 0}, {-1, 0}], {i, ndim}],
Table[Text[maxs[[i]] // ToString, {i, 1}, {-1, 0}], {i,ndim}]
},
Joined -> True,

Axes -> False];

To test, we generate 6-dimensional random data (here its 15 points), where each coordinate is randomly distributed between two random bounds.


d = Transpose@Table[
RandomReal[{Min@#, Max@#} &@RandomInteger[{0, 10}, 2], 15],
{6}]
parallelPlot@d

enter image description here


Comments

Popular posts from this blog

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...