1
$\begingroup$

I have the following graph:

enter image description here

  1. Due to opacity, my legend coloring is not matching my graphs and it might be confusing. Is there any remedy?

  2. I could not get the coloring what I wanted due to the opacity. It, indeed, hard to predict what I would get due to having multiple transparent surfaces on top of each other. I'm wondering if I can "randomly" assign "different" colors to the surfaces and run it many times so that I can eventually happen to like one combination.

I have two less related questions. But since they can probably be done quickly and trivially, I squeezed them in this question. I appreciate if one can advice me on these two.

  1. How to move the temperature label to the left side axis.

  2. I could not get my plot in orthogonal view or projection. For example, that's why my 90-degree rotated axis text "temperature" looks awkwardly standing next to the axes. What is the best practice in Mathematica-generated graphs? The other axes labels are even worse. I have no problem doing this with MATLAB or R but I'm stuck here.

Here is my code:

labels = {Style["45nm", 20], Style["32nm", 20], Style["22nm", 20], 
   Style["14nm", 20], Style["10nm", 20], Style["7nm", 20], 
   Style["5nm", 20]};
thick = {1.17, 1.38, 1.56, 2.34, 2.9, 4.12, 4.76};
colorz = {{Red, Opacity[0.5]}, {Blue, Opacity[0.5]}, {Yellow, 
    Opacity[0.5]}, {Purple, Opacity[0.5]}, {Orange, 
    Opacity[0.5]}, {Pink, Opacity[0.5]}, {Green, Opacity[0.5]}};
Plot3D[Table[ 
   Legended[(10^-7*thick[[index]])*(i /w)^2, 
    labels[[index]]], {index, 1, 7}] // Evaluate,
 {i, $MachineEpsilon, 1*^-4}, {w, 20*^-9, 50*^-9}, 
 PlotStyle -> colorz, Mesh -> False, ClippingStyle -> None, 
 PlotPoints -> 50, PlotRange -> All,
 AxesLabel -> {"current(uA)", "width(nm)", 
   Rotate["temperature rise", Pi/2]}
 (*,AxesLabel\[Rule]{Rotate["current(uA)",-.85],Rotate["width(nm)",.\
27],Rotate["temperature rise",Pi/2]}*)
 , Ticks ->
  {
   Table[{i, i*10^3}, {i, {0, 0.5*^-4, 1.0*^-4}}],
   Table[{w, w*10^9}, {w, {20*^-9, 30*^-9, 40*^-9, 50*^-9}}],
   Table[{t, ScientificForm[t]}, {t, {1, 5, 10}}]
   },
 BaseStyle -> {FontSize -> 20}
 , AxesStyle -> Black
 , ViewPoint -> {Pi*2, -Pi, 4.7}
 (*,PlotTheme\[Rule]"Detailed"*)
 , BoxRatios -> {1, 1, 0.7}
 , ImageSize -> 600, BoxStyle -> Directive[Red, Thickness[0.002]], 
 AxesStyle -> Directive[Orange, 12]
 , FaceGrids -> {{0, -1, 0}, {1, 0, 0}}
 , FaceGridsStyle -> Directive[Black, Dashed, Thickness[0.002]
   ]]
$\endgroup$
  • $\begingroup$ AFAIK there is no easy way to make axes labels be parallel to the axes. $\endgroup$ – Alexey Popkov Sep 16 '17 at 5:25
3
$\begingroup$

I can't answer all your questions, but I can tell you that the reason your colors don't match the graph is because the different plots distort the color of the plots on top. So really, the colors shown in the legend are really the colors shown in the graph, its just the way it is shown.

My way around legend issues is to just build my own legend using graphics. In your case, we need to solve the color issue. You can make the legend appear the same as in the graph by stacking the proper amount of shapes and colors on top of each other. I just start from the bottom of your stack in the graph and match squares on top of each other:

Table[Graphics[Table[Style[Rectangle[{0, 0}], colorz[[index]]], {index, 1, index2}], 
  ImageSize -> 80], {index2, 1, 7}]

output

so the first entry there is a single square matching your colorz[[1]] coloring specification. The second entry is two squares – the first colored colorz[[1]] and the second colorz[[2]]. The rest continue to build.

Now you can get creative and place these squares next to the actual legend entries and put them together. A quick and not quite complete example:

labels = MapThread[({Style["45nm", #1], Style["32nm", #1], 
      Style["22nm", #1], Style["14nm", #1], Style["10nm", #1], 
      Style["7nm", #1], Style["5nm", #1]}) & , {{10}}][[1]];

legendcol = 
  Table[Table[
    Style[Rectangle[{0, 0}], colorz[[index]]], {index, 1, 
     index2}], {index2, 1, 7}];

col = Table[
  Graphics[{legendcol[[i]], Inset[labels[[i]], {2.5, 0.5}]}], {i, 1, 
   7}];

Remove the legended in your plot function:

plot = Plot3D[
  Table[Style[(10^-7*thick[[index]])*(i/w)^2, 
     colorz[[index]]], {index, 1, 7}] // 
   Evaluate, {i, $MachineEpsilon, 1*^-4}, {w, 20*^-9, 50*^-9}, 
  PlotStyle -> colorz, Mesh -> False, ClippingStyle -> None, 
  PlotPoints -> 50, PlotRange -> All, 
  AxesLabel -> {"current(uA)", "width(nm)", 
    Rotate["temperature rise", Pi/2]}
  (*,AxesLabel\[Rule]{Rotate["current(uA)",-.85],Rotate[
  "width(nm)",.27],Rotate["temperature rise",Pi/2]}*), 
  Ticks -> {Table[{i, i*10^3}, {i, {0, 0.5*^-4, 1.0*^-4}}], 
    Table[{w, w*10^9}, {w, {20*^-9, 30*^-9, 40*^-9, 50*^-9}}], 
    Table[{t, ScientificForm[t]}, {t, {1, 5, 10}}]}, 
  BaseStyle -> {FontSize -> 20}, AxesStyle -> Black, 
  ViewPoint -> {Pi*2, -Pi, 4.7}
  (*,PlotTheme\[Rule]"Detailed"*), BoxRatios -> {1, 1, 0.7}, 
  ImageSize -> 600, BoxStyle -> Directive[Red, Thickness[0.002]], 
  AxesStyle -> Directive[Orange, 12], 
  FaceGrids -> {{0, -1, 0}, {1, 0, 0}}, 
  FaceGridsStyle -> Directive[Black, Dashed, Thickness[0.002]]];

GraphicsRow[{plot, GraphicsColumn[col] // DisplayForm}]

Now you will have to play with the dimensions and get it to fit in there real nice so there's still some trial and error there.

If you want to randomly generate colors you could just use a RNG with the RGBColors function:

colorz = Table[{RGBColor[RandomReal[], RandomReal[], RandomReal[]], 
   Opacity[0.5]}, {i, 1, 7}]
$\endgroup$
  • $\begingroup$ +1. Nice explanation! $\endgroup$ – Alexey Popkov Sep 15 '17 at 20:13
1
$\begingroup$

Haff nicely explained how you can achieve matching of colors of the legend with colors of the plot in the presence of transparency. I'll show how you can randomly assign different colors to the surfaces.

Suppose pl is a variable containing the output of your code in the OP. Then the following will replace existing colors (defined in colorz) with randomly chosen ones:

newColors = RandomColor[Length[colorz]];
pl /. Thread[colorz[[All, 1]] -> newColors]

plot

Note that before the replacement you can sort the random colors according to their brightness, saturation or the corresponding gray tone. For example, sorting by brightness:

newColors = SortBy[ColorConvert[newColors, "HSB"], Last];

Sorting by gray tone:

newColors = SortBy[newColors, ColorConvert[#, "Grayscale"][[1]] &]

In addition, this answer of mine shows how you can arbitrarily position labels on a plot.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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