4
$\begingroup$

I'm trying to visualize some data using ListDensityPlot. Some of the data points may have bad values like Indeterminate which may come from taking Log10 of a negative number. When drawing the figure, I wish to leave these places blank.

Here is a minimal example:

l = {{1, 1, 0}, {1, 2, 0.5}, {2, 1, 1}, {2, 2, Indeterminate}};
ListDensityPlot[l, InterpolationOrder -> 0, 
 ColorFunction -> "Rainbow"]

and the outcome is the left plot attached. Notice how the cell at {2,2} is extrapolated from the neighboring points. What I want is to leave this cell blank (for example in White), so I tried

Clear[cf]
cf[x_] := ColorData["Rainbow"][x] /; NumericQ[x]
cf[x_] := White
ListDensityPlot[l, ColorFunction -> cf, InterpolationOrder -> 0, 
 ColorFunctionScaling -> False]

but the result is the same (the mid panel).

What I want is something like the right panel, which I plotted using

ArrayPlot[{{0.5, Indeterminate}, {0, 1}}, ColorFunction -> cf]

Unfortunately ArrayPlot or MatrixPlot is not straightforwardly usable in my practical case because I have some non-uniform grid. Ultimately it is doable, perhaps by remeshing my data and so on. But before that I'm wondering is there anything can be done using ListDensityPlot?

In the past I have used the following way: (i) replace all the non-numeric values in l by 0.5*min where min is the minimal value in l[[;;,-1]], and then (ii) set PlotRange->{0.9*min,All} for ListDensityPlot. This works but becomes rather complicated when plotting several sets of data in a row which share the same color bar.

Any advice is welcome!

enter image description here

========= Edit on 16:37 May 18 =========

The l in my case is a scalar field on a spherical grid. Something like this:

grid = Table[{r*Sin[th], r*Cos[th]},
  {r, 1, 10, 0.1}, {th, 0, Pi, 0.1}] // Flatten[#, 1] &;
values = Log10@RandomReal[{-1, 1}, grid // Length];
l = Flatten /@ Transpose[{grid, values}];
$\endgroup$
3
  • 1
    $\begingroup$ what does l look like in your practical case with non-uniform grid? $\endgroup$
    – kglr
    May 18, 2023 at 8:23
  • $\begingroup$ @kglr hi, please see my edit in the post $\endgroup$
    – H. Zhou
    May 18, 2023 at 8:39
  • $\begingroup$ thank you H. Zhou $\endgroup$
    – kglr
    May 18, 2023 at 8:54

1 Answer 1

2
$\begingroup$

If you try the following, you will see that the ColorFunction never sees "Indeterminate":

l = {{1, 1, 0}, {1, 2, 0.5}, {2, 1, 1}, {2, 2, Indeterminate}};
Clear[cf]
cf[x_] := Print[x];

ListDensityPlot[l, InterpolationOrder -> 0, ColorFunction -> cf];

enter image description here

We can create a work-around by changing "Indeterminante" to some special number, e.g. 10^6 and then define the ColorFunction to give White for this number:

ll = l /. Indeterminate -> 10^6;
Clear[cf]
cf[x_] := If[x == 10^6, White, ColorData["Rainbow"][x]]

ListDensityPlot[ll, ColorFunction -> cf, InterpolationOrder -> 0, 
 ColorFunctionScaling -> False]

enter image description here

$\endgroup$
2
  • $\begingroup$ Hi, thanks for your answer! The behavior of ColorFunction is quite interesting. Why this is so? $\endgroup$
    – H. Zhou
    May 18, 2023 at 8:50
  • $\begingroup$ You will have to ask at: [email protected] $\endgroup$ May 18, 2023 at 8:59

Your Answer

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

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