1
$\begingroup$

I have the below codes to create contour two plots that I then merge together to show at the same time. They are from mesh maps of above and below a dam so i cannot make the contour plots together or it shows something I do not want. However, I would like the legend to show negative 2 to positive 2 (so that I can make the legend/scale consistent between different data sets). But using my current code (and iterations I have tried) I cannot get this.

I would also like the colors to be consistent between the data sets rather than stretching to the data for each year (so that changes of 0.1 for one data set are the same color as changes of 0.1 from other data sets).

Another small thing I haven't figured out is stopping the graphic from having two scales/legends when I show both sections together. I could just crop out the extra legend when I use it but ideally I would like to remove this step.

Creating one section:

ContourUpstream1921 = 
 ListContourPlot[Upstreammesh2diff1921, MaxPlotPoints -> 100, 
  ColorFunction -> (ColorData[{"TemperatureMap", "Reverse"}][#] &), 
  PlotLegends -> Automatic, PlotRange -> All]

enter image description here Creating the second section:

ContourDownstream1921 = 
 ListContourPlot[Downstreammesh2diff1921, MaxPlotPoints -> 100, 
  ColorFunction -> (ColorData[{"TemperatureMap", "Reverse"}][#] &), 
  PlotLegends -> Automatic, PlotRange -> All]

enter image description here Merging the sections:

Show[ContourDownstream1921, ContourUpstream1921, PlotRange -> All]

enter image description here

$\endgroup$
2
  • $\begingroup$ Use PlotRange->{-2,2} to choose the range of the color bar, and use First to remove the legend from one of the plots before combining them with Show, e.g. Show[…, First[…]]. Alternatively simpliy don't add the legend to one of the plots by dropping the PlotLegends->Automatic. $\endgroup$
    – Lukas Lang
    Commented Apr 6, 2023 at 7:09
  • $\begingroup$ @LukasLang The issue I get when I use that plot range is that the legend and contours are too large for what I want. Ideally, I want the contours and color change at intervals of 0.1 to show more nuances. I change the contours back to 0.2 using this code Contours -> Range[-2, 2, 0.1] but it messes up the legend again, making the legend back to the range of the data rather than -2 to 2 $\endgroup$ Commented Apr 6, 2023 at 15:17

1 Answer 1

2
+50
$\begingroup$

Answers to the requirements:

colors to be consistent between the data sets rather than stretching to the data for each year

What causes the problem is that data is automatically rescaled from MinMax[data] to {0,1} before passing to ColorFunction, so we need ColorFunctionScaling->False, and then rescale the ColorFunction by ourselves. We can use Rescale but a more clever way is to use ColorData directly:

{min, max} = {-2, 2};
colorfunc = ColorData[{"TemperatureMap", Reverse@{min, max}}];

legend to show negative 2 to positive 2

You can explicitly use BarLengend to specify the range, while using Automatic to match to the ColorFunction in the plot. If you want to control the ticks, use Method for BarLegend

BarLegend[{Automatic, {min, max}}]

stopping the graphic from having two scales/legends

Extract the plot from Legended using First.

mock data

Since you didn't post your data for ContourUpstream1921 & ContourDownstream1921, I'll firstly mock up some data to show the result. I'm intentionally setting the range of data to be {-2,1} and {-1,2} to show the difference in colorbar.

SeedRandom@1234;
data1 = Flatten /@ Thread@{RandomPoint[Disk[], 100], RandomReal[{-2, 1}, 100]};
data2 = Flatten /@ Thread@{RandomPoint[Rectangle[{1, 1}], 100], RandomReal[{-1, 2}, 100]};

Here's the plots mimicking the OP's plots: One can see that the two regions have similar colors, which is wrong since they have different data range. There are also 2 different legends.

{MaxPlotPoints -> 100, ColorFunction -> ColorData[{"TemperatureMap", "Reverse"}], PlotLegends -> Automatic, 
   InterpolationOrder -> 1, Contours -> Range[-2, 2, .2]};
ListContourPlot[data1, %];
ListContourPlot[data2, %%];
Show[%, %%, PlotRange -> All, PlotLabel -> "naive plot"]

enter image description here

solution

{min, max} = {-2, 2};(*explicitly set data range for reuse*)
colorfunc = ColorData[{"TemperatureMap", Reverse@{min, max}}];(*manually rescale ColorFunction*) 
 (* Another way:  
 rescale[x_]=Rescale[x,{min,max},{0,1}];
 colorfunc=ColorData[{"TemperatureMap","Reverse"}]@rescale@#&;
 *) 
 
options = {MaxPlotPoints -> 100, 
     InterpolationOrder -> 1, 
     ColorFunctionScaling -> False,(*disable automatic rescaling*)
     ColorFunction -> colorfunc, 
     PlotRange -> {min, max}, 
     Contours -> Range[min, max, .2], 
     PlotLegends -> BarLegend[{Automatic, {min, max}}, Automatic, Method -> {"Ticks" -> Range[min, max, .4]}] 
    }; 
 (*plotting with the same options*)
ListContourPlot[data1, options]
ListContourPlot[data2, options] 
 (*combine the plots,with only the first legend *)
Show[%, First@%%, PlotRange -> All]

enter image description here

Now both plots shares the same options and scale, so the combined plot is consistent.

$\endgroup$

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.