Clear[ListPointPlot4D]Options[ListPointPlot4D]={Method"Projection"};ListPointPlot4D[points_List,OptionsPattern[]]:=Module[{Rotate4D,graphs=Thread[List[Subsets[Range[4],{3}],Reverse[Range[4]]]]},Rotate4D[data_List,xy_,yz_,xz_,xw_,yw_,zw_]:=RotationTransform[2Pixy,{{1,0,0,0},{0,1,0,0}}][RotationTransform[2Piyz,{{0,1,0,0},{0,0,1,0}}][RotationTransform[2Pixz,{{1,0,0,0},{0,0,1,0}}][RotationTransform[2Pixw,{{1,0,0,0},{0,0,0,1}}][RotationTransform[2Piyw,{{0,1,0,0},{0,0,0,1}}][RotationTransform[2Pizw,{{0,0,1,0},{0,0,0,1}}][N[data]]]]]]];If[OptionValue[Method]=="Projection",Manipulate[With[{mat=GroupBy[Rotate4D[points,Angle3D[[1]],Angle3D[[2]],0,Angle4D[[1]],Angle4D[[2]],0],#[[4]]&]},Legended[Graphics3D[Thread[List[Table[Opacity[0.5,x],{x,Hue/@(0.8*Rescale@Keys[mat])}],Table[Thick,Length[mat]],Table[If[MatrixRank[#-First[dimLevel]&/@dimLevel]>=3,ConvexHullMesh[dimLevel],ConvexHullRegion[dimLevel]],{dimLevel,Table[Dot[x[[1]],1/(distance-x[[2]])*IdentityMatrix[{4,3}]],{x,Thread[List[Values[mat],Keys[mat]]]}]}]]],FaceGrids->All,FaceGridsStyleDirective[LightGray,Dashed],Axes->True,TicksAutomatic],BarLegend[{Array[Hue,2,{0,0.8}],{Min[Keys[mat]],Max[Keys[mat]]}}]]],{distance,10,-10},{Angle3D,{0,1},{1,0},ControlType->Slider2D},{Angle4D,{0,1},{1,0},ControlType->Slider2D}],Manipulate[Grid[Partition[Table[With[{mat=GroupBy[Rotate4D[points,Angle3D[[1]],Angle3D[[2]],0,Angle4D[[1]],Angle4D[[2]],0],#[[Last[graph]]]&]},Legended[Labeled[Graphics3D[Thread[List[Table[Opacity[0.5,x],{x,Hue/@(0.8*Rescale@Keys[mat])}],Table[Thick,Length[mat]],Table[If[MatrixRank[#-First[dimLevel]&/@dimLevel]>=3,ConvexHullMesh[dimLevel],ConvexHullRegion[dimLevel]],{dimLevel,Values[mat][[All,All,First[graph]]]}]]],FaceGrids->All,FaceGridsStyleDirective[LightGray,Dashed],TicksAutomatic],StringForm["Dimension `` reduced",Last[graph]],Top],BarLegend[{Array[Hue,2,{0,0.8}],{Min[Keys[mat]],Max[Keys[mat]]}}]]],{graph,graphs}],2]],{Angle3D,{0,1},{1,0},ControlType->Slider2D},{Angle4D,{0,1},{1,0},ControlType->Slider2D}]]]