0
$\begingroup$

Here comes a sample data set

data = {{1.03971, 0.00617284, 12.11, 0.227037, 1}, {1.0231, 0.0216931, 27.23, 1.40703, 1}, {1.02864, -0.0294533, 1450, 0.0821789, 1}, {1.01636, -0.0149912, 16.89, 1.02227, 1}, {0.938865, -0.00899471, 68.94, 0.0000322202, 1}, {0.955953, 0.0199295, 1.89, 0.00448189, 9}, {1.03321, 0.0329806, 84.23, 0.094761, 1}, {1.02406, 0.0393298, 13.21, 0.099565, 1}, {0.9728, -0.00194004, 1000, 0.000845306, 0}, {1.00649, -0.00582011, 62.1, 0.0286736, 1}}; 

The first two columns correspond to the coordinates $(x,y)$, while the other three are some indicators. Now we want to plot those $(x,y)$ coordinates for which the fifth column is equal to 1, while the color of each point should be according to the value of the third column.

First we define a custom color function

valrange = {0, 100}; data[[All, 3]] = Rescale[data[[All, 3]] // N, valrange]; colfunc[x_, cf_] := If[x[[5]] == -2 || x[[5]] == -1 || x[[5]] == 0 || x[[5]] == 2 || x[[5]] == 9 || x[[5]] == 99, White, ColorData[cf][1 - x[[3]]]]; 

Then the graphics of the points

S0 = Graphics[{PointSize[0.01], Point[#[[1 ;; 2]], VertexColors -> colfunc[#, "Rainbow"]] & /@ data}]; 

and a custom colorbar

Clear[colorbar] colorbar[{min_, max_}, colorFunction_: Automatic, divs_: 150] := DensityPlot[y, {x, 0, 0.1}, {y, min, max}, AspectRatio -> 10, PlotRangePadding -> 0, PlotPoints -> {2, divs}, MaxRecursion -> 0, Frame -> True, FrameLabel -> {{None, Row[{Subscript["t", "esc"]}]}, {None, None}}, LabelStyle -> Directive[FontFamily -> "Helvetica", 20], FrameTicks -> {{None, All}, {None, None}}, FrameTicksStyle -> Directive[FontFamily -> "Helvetica", 20, Plain], ColorFunction -> colorFunction] 

Finally we merge together the graphics with the colorbar

With[{opts = {ImageSize -> {Automatic, 400}}, cf = "Rainbow"}, Row[{Show[{S0}, Axes -> False, Frame -> True, FrameLabel -> {"x", "y"}, RotateLabel -> False, LabelStyle -> Directive[FontFamily -> "Helvetica", 20], AspectRatio -> 3/4, ImagePadding -> {{90, 10}, {60, 40}}, opts], Show[colorbar[valrange, ColorData[cf][1 - #] &], ImagePadding -> {{10, 80}, {60, 40}}, opts]}]] 

which produces the following

enter image description here

The range of the colorbar is between 0 and 100, according to valrange. However in the real data set there are some few initial conditions which have $(x,y)$ coordinates with fifth column equal to 1, while the value of the third column is higher than 100 (see e.g., the third element of data list).

My question: Is there an elegant way to set automatically the higher label of the color bar "> 100", instead of simply "100"?

Many thanks in advance!

EDIT

If I set FrameTicks -> {{None, {0, 20, 40, 60, 80, "> 100"}}, {None, None}}, it does not work.

$\endgroup$
1
  • $\begingroup$ You're misusing the syntax of FrameTicks. When you provide it with a simple list, you need to give it numeric values of where the ticks will appear, it obviously can't interpret ">100" properly. In this case you need to provide it with a list of the form {{value, label}, {value, label}, ...}. For a "nice" range like {0, 100} it's quite easy to handle this, but what if you feed it a range like {5, 98}? $\endgroup$ Commented Mar 6, 2017 at 10:38

1 Answer 1

1
$\begingroup$

This is hopefully sufficiently general to handle most cases.

First roll a little helper function:

ticksHelper[min_, max_] := Module[ { out = Charting`ScaledTicks[{Identity, Identity}][min, max] // #[[;; , {1, 2}]] & // Cases[#, {_, _?NumberQ}] & }, If[ First@Last@out < max, AppendTo[out, {max, "> " <> ToString@max}], out[[-1, -1]] = "> " <> ToString@max ]; out ] 

Then modify the definition of your colorbar to include the helper:

colorbar[{min_, max_}, colorFunction_: Automatic, divs_: 150] := DensityPlot[y, {x, 0, 0.1}, {y, min, max}, AspectRatio -> 10, PlotRangePadding -> 0, PlotPoints -> {2, divs}, MaxRecursion -> 0, Frame -> True, FrameLabel -> {{None, Row[{Subscript["t", "esc"]}]}, {None, None}}, LabelStyle -> Directive[FontFamily -> "Helvetica", 20], FrameTicks -> {{None, ticksHelper[min, max]}, {None, None}}, FrameTicksStyle -> Directive[FontFamily -> "Helvetica", 20, Plain], ColorFunction -> colorFunction] 

It might be slightly problematic for a range like {0., 101.} though (you'll get a label at 100 and then a > 101 label at 101 and they'll overlap). It should be quite easy to fix, the exact manner depending on your needs.

$\endgroup$
1
  • 1
    $\begingroup$ Nice! It works fine because always I use range with round limits. $\endgroup$ Commented Mar 6, 2017 at 11:37

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.