ListPlot: individual point colors - wolfram-mathematica

I've got a simple ListPlot like
list2 = Table[{x, Sqrt[x]}, {x, 0, 100}];
Now I want to color specific points with RED, say every 5th point, I tried
mycolor[x_] /; Mod[x, 5] == 0 = Red;
mycolor[_] = Blue;
Now
ListPlot[#, PlotStyle -> AbsolutePointSize[3], ColorFunction ->
mycolor[#[[All, 1]], ColorFunctionScaling -> False]] &[list2]
doesnt work quite right, all points are still blue.
What is wrong here?
Thanks,
archi

Here is an easy way to get the result you're after :-
list2 = Table[{x, Sqrt[x]}, {x, 0, 100}];
mycolor[x_] := If[Mod[x, 5] == 0, Red, Blue];
mycolors = mycolor /# list2[[All, 1]];
ListPlot[List /# list2,
PlotStyle -> Map[{AbsolutePointSize[3], #} &, mycolors]]
Alternatively, with a colour function, thanks to rm -rf's answer on george's link :-
list2 = Table[{x, Sqrt[x]}, {x, 0, 100}];
mycolor = Function[{x, y}, If[Mod[x, 5] == 0, Red, Blue]];
ListLinePlot[list2,
PlotStyle -> AbsolutePointSize[3], ColorFunction -> mycolor,
ColorFunctionScaling -> False] /. Line -> Point
Further to comment
For different plot markers I have reverted to the easy method. In order to apply different styles and plot markers in ListPlot the differently styled points have to be in separate lists, hence List /# list2. (Only two lists would actually be necessary though.)
Clear[mycolor];
list2 = Table[{x, Sqrt[x]}, {x, 0, 100}];
mycolor[x_] := If[Mod[x, 5] == 0,
{Red, "\[FilledUpTriangle]", 14},
{Blue, "\[FilledSmallCircle]", 6}];
mycolorspec = mycolor /# First /# list2;
ListPlot[List /# list2,
PlotMarkers -> Apply[Style[#2, FontSize -> #3, #1] &,
mycolorspec, {1}]]

Related

Could not combine the graphics objects in Show[

I get this error for the Show method, why? :/
sol = First#
NDSolve[{eq1ad, eq2ad, eqrad} U CondizioniIniziali, {q1, q2,
qr}, {t, 0, T}]
p1 = ParametricPlot3D[
{xE, yE, zE} /. sol,
{t, 0, T},
AxesLabel -> {"x[t]", "y[t]", "z[t]"},
BoxRatios -> {1, 1, 1},
PlotStyle -> Red
]
Manipulate[
Show[
p1,
ListLinePlot[
{{0, 0, 0}, {xB, yB, zB}, {xE, yE, zE}} /. sol /. t -> time,
PlotStyle -> {Thick, Red}
]
],
{time, 0, T}
]
Is it maybe because I can't combine a ParametricPlot3d with Show?
I think you are trying to combine a 2D ListLinePlot with a 3D ParametricPlot3D. Reading the documentation for ListLinePlot seems to show that it only accepts 2D points, not 3D points.
You might be able to adapt something like this
T=2;
p1 = ParametricPlot3D[{Sin[t],Cos[t],t^2}, {t,0,T}];
Show[p1, Graphics3D[ Line[{{0, 0, 0}, {1/2,1/2,2}, {1/3, 1/3,3}}]]]
which can turn a list of 3D points into a Line into a Graphics3D and then combine that your ParametricPlot3D

Mathematica re-use the ColorFunction of another plot

I would very much appreciate your help on my problem.
I would like to use the same color function that applies to the plot of data1 when plotting data2.
For example:
data1 = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
ListPointPlot3D[data1, PlotStyle -> PointSize[0.02],
ColorFunction -> Function[{x, y, z}, RGBColor[x, y, z]]]
and next I wish to plot another data (of same dimensions) using the previous colors in the same exact order (there is an unknown function transforming data1 to data2):
data2 = {{1, 1, 0}, {1, 0, 1}, {0, 1, 1}};
ListPointPlot3D[data2, PlotStyle -> PointSize[0.02],
ColorFunction -> Function[{x, y, z}, fun[x, y, z]]]
but for example a straightforward trial as follows will not work (although fun[] as such does work):
fun[r_, g_, b_] :=Table[RGBColor[data1[[i]]], {i,
Length[data1]}][[Position[data2, {r, g, b}][[1, 1]]]]
The gotcha in this is that ListPointPlot3D takes your integer data and converts to floats which it passes to your ColorFunction, so if you define your color function for discrete integers it fails to match the floats. Try this.. (Your approach may work as well if you work with real data )
data1 = N#{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
cfun1[x_, y_, z_] := RGBColor[x, y, z]
ListPointPlot3D[data1, PlotStyle -> PointSize[0.02],
ColorFunction -> cfun1]
data2 = N#{{1, 1, 0}, {1, 0, 1}, {0, 1, 1}};
MapThread[ (cfun2[#2[[1]], #2[[2]], #2[[3]]] = cfun1 ## #1) & ,
{data1, data2}]
ListPointPlot3D[data2, PlotStyle -> PointSize[0.02],
ColorFunction -> cfun2]
A bit of an aside, but you likely would be better off working with graphics primitives, which would look something like this:
colors = cfun1 /# data1;
Graphics3D#MapThread[ {#1, Point##2} & , {colors, data1} ]
Graphics3D#MapThread[ {#1, Point##2} & , {colors, data2} ]
Use the colours from data1 in the PlotStyle option of the data2 plot. The list of directives in the PlotStyle refer to each data series so you have to make each point its own data series. I also take it that the values may not be between zero and one so rescale them for data2's use of RGBColor.
ListPointPlot3D[data1, PlotStyle -> PointSize[0.02],
ColorFunction -> Function[{x, y, z}, RGBColor[x, y, z]]]
rs = MinMax /# Transpose#data1;
ListPointPlot3D[List /# data2,
PlotStyle -> ({PointSize[0.02], RGBColor[Quiet#Thread[Rescale[#, rs]]]} & /# data1)]
Hope this helps.

How to generate function name automatically in mathematica?

When I draw multiple functions like exp,2^x,3^x, is it possible to generate a label of each function?
My code now:
Plot[{Exp[x], 2^x, 3^x}, {x, -5, 2}, AspectRatio -> Automatic, PlotStyle -> {Red, Green, Blue}]
What I mean is generate 3 labels in this case to tell the user what function it is.
Such as:
How do you generate this?
Perhaps this works: Use Tooltip in Plot to generate a Graphics object with tooltips. Then rewrite the tooltip to place the desired text in the desired location:
Plot[
Tooltip#{Exp[x], 2^x, 3^x}, {x, -5, 2},
AspectRatio -> Automatic,
PlotStyle -> {Red, Green, Blue},
PlotRange -> All,
PlotRangePadding -> 1.1] /.
{
Tooltip[{_, color_, line_}, tip_]
:>
{Text[Style[tip, 14], {.25, 0} + line[[1, -1]]], color, line}
}
I am not sure what the rules are for adding another, different answer for the same question. But here is another, different way to do it. If I am supposed to add this to my first answer, I can do that.
You can add the text labels, by hand, using Text commands. I think it looks better. Here is one way:
Clear[x];
funs = {Exp[x], 2^x, 3^x};
funNames = Style[#, 12] & /# funs;
(*the x-axis plot range used *)
from = -5; to = 2;
(* generate the coordinates at the end of the plot lines*)
pos = Map[{to, #} &, funs /. x -> to];
(*generate the text labels *)
text = Map[Text[#[[1]], #[[2]], {-1, 0}] &, Thread[{funNames, pos}]];
Plot the final result (added a little of padding to plot range so that
the labels added are seen completely)
Plot[funs, {x, from, to},
PlotRangePadding -> {1, 1},
PlotStyle -> {Red, Green, Blue},
PlotRange -> All,
Epilog -> text
]
update (1)
Sam asked below for an simpler way. I am not sure now. But one way to make it easier to use this method, is to make a function and then simply call this function once to generate the Text labels. You can put this function where you put all your other functions you use all the time, and just call it.
Here is something: First write the function
(*version 1.1*)
myLegend[funs_List, (*list of functions to plot*)
x_, (*the independent variable*)
from_?(NumericQ[#] && Im[#] == 0 &),(*the x-axis starting plot range*)
to_?(NumericQ[#] && Im[#] == 0 &) (*the x-axis ending plot range*)
] := Module[{funNames, pos, text, labelOffset = -1.3},
(*make label names*)
funNames = Style[#, 12] & /# funs;
(*generated the coordinates at the end of the plot lines*)
pos = Map[{to, #} &, funs /. x -> to];
(*generate the Text calls*)
text = Map[Text[#[[1]], #[[2]], {labelOffset, 0}] &,
Thread[{funNames, pos}]]
];
And now just call the above any time you want to plot with labels. It will be just 1-2 extra lines of code. like this:
Clear[x]
from = -5; to = 2;
funs = {Exp[x], 2^x, 3^x};
Plot[funs, {x, from, to}, PlotRangePadding -> {1, 1},
PlotStyle -> {Red, Green, Blue}, PlotRange -> All,
Epilog -> myLegend[funs, x, from, to]]
Here are few examples:
You can modify it as you want.
Alternative way with Tooltip displaying labels while the mouse pointer is at the function graphs :
Plot[Tooltip#{Exp[x], 2^x, 3^x}, {x, -5, 2}, AspectRatio -> Automatic,
PlotStyle -> {Red, Green, Blue}]
One way is to use PlotLegends
(I do not like it too much, but it is an easy way to do what you want)
<< PlotLegends`
Clear[x];
funs = {Exp[x], 2^x, 3^x};
legends = Map[Text#Style[#, "TR", 12] &, funs];
Plot[Evaluate#funs, {x, -5, 2}, AspectRatio -> Automatic,
PlotStyle -> {Red, Green, Blue}, PlotLegend -> legends]
see help to customize the legend more. The above uses defaults.
http://reference.wolfram.com/mathematica/PlotLegends/tutorial/PlotLegends.html

Coloring plot in Mathematica according to labels

I have a dataset with labels which I would like to plot with points colored according to their label. Is there a simple way how to get current line numer inside plot, so that I can determine which category does the point belong to?
I understood that x,y,z are the coordinates of plotted data, but it doesn't help for the external labels.
This is quite ugly and it works just on sorted dataset with regular distribution.
data = Import["http://ftp.ics.uci.edu/pub/machine-learning-databases/iris/iris.data"];
data = Drop[data, -1]; (*there one extra line at the end*)
inData = data[[All, 1 ;; 4]];
labels = data[[All, 5]];
ListPlot3D[inData,
ColorFunction ->
Function[{x, y, z},
If[y < 0.33, RGBColor[1, 1, 0.],
If[y < 0.66, RGBColor[1, 0, 0.], RGBColor[1, 0, 1]]
]
]
]
Expected result:
Suppose that points is the lists of coordinates and labels a list of the corresponding labels so for example
points = Flatten[Table[{i, j, Sin[i j]},
{i, 0, Pi, Pi/20}, {j, 0, Pi, Pi/10}], 1];
labels = RandomChoice[{"label a", "label b", "label c"}, Length[points]];
Each label corresponds to a colour which I'm writing as a list of rules, e.g.
rules = {"label a" -> RGBColor[1, 1, 0],
"label b" -> RGBColor[1, 0, 0], "label c" -> RGBColor[1, 0, 1]};
Then the points can be plotted in the colour corresponding to their label as follows
ListPointPlot3D[Pick[points, labels, #] & /# Union[labels],
PlotStyle -> Union[labels] /. rules]
Edit
To colour individual points in a ListPlot3D you can use VertexColors, for example
ListPlot3D[points, VertexColors -> labels /. rules, Mesh -> False]
For Example:
(* Build the labeled structure and take a random permutation*)
f[x_, y_] = Sqrt[100 - x x - y y];
l = RandomSample#Flatten[{Table[{{"Lower", {x, y, f[x, y] - 5}},
{"Upper", {x, y, 5 - f[x, y]}}},
{x, -5, 5, .1}, {y, -5, 5, .1}]}, 3];
(*Plot*)
Graphics3D[
Riffle[l[[All, 1]] /. {"Lower" -> Red, "Upper" -> Green},
Point /# l[[All, 2]]], Axes -> True]

Graphical Representation of Lists

Say I have three lists: a={1,5,10,15} b={2,4,6,8} and c={1,1,0,1,0}. I want a plot which has a as the x axis, b as the y axis and a red/black dot to mark 1/0. For. e.g. The coordinate (5,4) will have a red dot.
In other words the coordinate (a[i],b[i]) will have a red/black dot depending on whether c[i] is 1 or 0.
I have been trying my hand with ListPlot but can't figure out the options.
I suggest this.
a = {1, 5, 10, 15};
b = {2, 4, 6, 8};
c = {1, 1, 0, 1};
Graphics[
{#, Point#{##2}} & ###
Thread#{c /. {1 -> Red, 0 -> Black}, a, b},
Axes -> True, AxesOrigin -> 0
]
Or shorter but more obfuscated
Graphics[
{Hue[1, 1, #], Point#{##2}} & ### Thread#{c, a, b},
Axes -> True, AxesOrigin -> 0
]
Leonid's idea, perhaps more naive.
f[a_, b_, c_] :=
ListPlot[Pick[Transpose[{a, b}], c, #] & /# {0, 1},
PlotStyle -> {PointSize[Large], {Blue, Red}}]
f[a, b, c]
Edit: Just for fun
f[h_, a_, b_, c_, opt___] :=
h[Pick[Transpose[{a, b}], c, #] & /# {0, 1},
PlotStyle -> {PointSize[Large], {Blue, Red}}, opt]
f[ ListPlot,
Sort#RandomReal[1, 100],
Sin[(2 \[Pi] #)/100] + RandomReal[#/100] & /# Range[100],
RandomInteger[1, 100],
Joined -> True,
InterpolationOrder -> 2,
Filling -> Axis]
Here are your points:
a = {1, 5, 10, 15};
b = {2, 4, 6, 8};
c = {1, 1, 0, 1};
(I deleted the last element from c to make it the same length as a and b). What I'd suggest is to separately make images for points with zeros and ones and then combine them - this seems easiest in this situation:
showPoints[a_, b_, c_] :=
With[{coords = Transpose[{a, b}]},
With[{plotF = ListPlot[Pick[coords, c, #], PlotMarkers -> Automatic, PlotStyle -> #2] &},
Show[MapThread[plotF, {{0, 1}, {Black, Red}}]]]]
Here is the usage:
showPoints[a, b, c]
One possibility:
ListPlot[List /# Transpose[{a, b}],
PlotMarkers -> {1, 1, 0, 1} /. {1 -> { Style[\[FilledCircle], Red], 10},
0 -> { { Style[\[FilledCircle], Black], 10}}},
AxesOrigin -> {0, 0}]
Giving as output:
You could obtain similar results (to those of Leonid) using Graphics:
Graphics[{PointSize[.02], Transpose[{(c/. {1 -> Red, 0 -> Black}),
Point /# Transpose[{a, b}]}]},
Axes -> True, AxesOrigin -> {0, 0}]

Resources