1
$\begingroup$

Using MMA 12.0 on a Windows 10 machine.

I am trying to plot a list of points in a 3D plot. Each point has a different weight which I want to show using different point sizes. The points are also in different clusters and I want to show that using different colors. Let's say maybe three or four different colors. The total number of points in a plot would be between fifteen and twenty but I may end up producing more than a thousand of these plots.

The best that I have figured out is to use "ListPointPlot3D" with "Style". But it seems like that I can only specify one specification using Style. I can do either the color or the point size. I can't do both.

For example,

ListPointPlot3D[{Style[{0, 0, 1}, Green], Style[{1, 0, 0}, Red]}]

works perfectly fine, as expected, and I get one green point and one red point.

enter image description here

I can specify the point size on either one and it works.

ListPointPlot3D[{Style[{0, 0, 1}, PointSize[0.1]], 
  Style[{1, 0, 0}, Red]}]

enter image description here

ListPointPlot3D[{Style[{0, 0, 1}, Green], 
  Style[{1, 0, 0}, PointSize[0.1]]}]

enter image description here

But when I try to specify both the color and the point size for a point, both specifications are ignored.

ListPointPlot3D[{Style[{0, 0, 1}, Green, PointSize[0.5]], 
  Style[{1, 0, 0}, Red]}]

gives me neither a green point nor a large point.

enter image description here

The documentation for Style says that

Style[expr,spec1,spec2,...] allows the speci to be any list or sequence of the following:

But both, a sequence of specifications

Style[{0, 0, 1}, Green, PointSize[0.5]]

and a list of specifications

Style[{0, 0, 1}, {Green, PointSize[0.5]}]

fail.

How can I make this work? I hope this is not a bug or anything. Do I need to do something completely different?

One method that I can think of is

g1 = ListPointPlot3D[{Style[{0, 0, 1}, PointSize[0.05]], 
   Style[{1, 0, 0}, PointSize[0.03]]}, PlotStyle -> Green];
g2 = ListPointPlot3D[{Style[{0, 1, 1}, PointSize[0.02]], 
   Style[{0, 2, 0}, PointSize[0.04]]}, PlotStyle -> Red];
Show[g1, g2, PlotRange -> {{-1, 2}, {-1, 2}, {-1, 2}}]

enter image description here

This gives me what I want but feels inefficient and is probably slower. Is it? The code is longer, a bit uglier, and I have to manually figure out and specify the PlotRange because Show is not smart enough to figure out the optimal plot range. I would need to have 3-4 plots and then merge them into a single plot every time. Can this be done with a single ListPointPlot3D?

I have no great affinity for Style or even ListPointPlot3D. If there is a vastly superior (faster/more-efficient/easier-to-read/terse) method, then I wouldn't mind learning about it.

$\endgroup$

3 Answers 3

1
$\begingroup$

Not sure this makes things quite as compact as you'd like but what about

points = {{0, 0, 1}, {1, 0, 0}, {0, 1, 1}, {0, 2, 0}};
colors = {Green, Green, Red, Red};
size = {0.05, 0.03, 0.02, 0.04};

ListPointPlot3D[{#} & /@ points,
 PlotStyle -> ({#[[1]], PointSize[#[[2]]]} &) /@ Transpose[{colors, size}], 
 PlotRange -> {{-1, 2}, {-1, 2}, {-1, 2}}]

3D points

$\endgroup$
3
  • $\begingroup$ +1 Oh good lord, I messed around with such a vector approach for a while but gave up where colors and size can be vectors. I couldn't get it to work. Didn't realize that PlotStyle can be a list of lists. I'll wait to see if any other answers are posted. This will make my overall code much smaller. Thanks! $\endgroup$ Apr 25, 2020 at 19:28
  • $\begingroup$ Why do you have an anonymous function in the first argument, for points? Wouldn't just ListPointPlot3D[points,... work? Do we need the extra set of braces? $\endgroup$ Apr 25, 2020 at 19:39
  • $\begingroup$ Try it. I believe that the points need to be separated into separate lists otherwise just the first PlotStyle is used. $\endgroup$
    – JimB
    Apr 25, 2020 at 19:41
1
$\begingroup$

Multiple graphics directives like the color and point size can be passed to Style by using Directive. For example,

ListPointPlot3D[{
  Style[{{0, 0, 1}, {0, .1, 1}, {0, .2, 1}}, 
   Directive[Green, PointSize[0.02]]],

  Style[{{.2, 0, 1}, {.25, .1, 1}, {0.2, .2, 1}}, 
   Directive[Blue, PointSize[0.015]]],

  Style[{{.4, 0, 1}, {.45, .1, 1}, {0.4, .2, 1}}, 
   Directive[Red, PointSize[0.025]]]
  }]

enter image description here

$\endgroup$
1
  • $\begingroup$ +1 Ah, this is what I was missing. This wasn't obvious anywhere in the documentation or my search engine results. Thanks! $\endgroup$ Apr 25, 2020 at 19:35
1
$\begingroup$

You might want to look at BubbleChart3D

n = 20;

SeedRandom[1234]

points = RandomReal[{0, 1}, {n, 3}];

weights = RandomReal[{0.5, 1}, n];

Tailor the BubbleScale and ColorFunction to taste

BubbleChart3D[
 Append @@@ Transpose[{points, weights}],
 BubbleScale -> "Diameter",
 ColorFunction -> Function[{x, y, z, r},
   ColorData["Rainbow"][Norm[{x, y, z} - Mean[points]]]]]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.