2
$\begingroup$

This is current solution from a friend:

Block[{rawpic = 
   ParametricPlot[{x, y}, {x, 0, 1}, {y, 0, 1 - x}, 
      ColorFunction -> Function[{x, y}, RGBColor[x, y, 1 - x - y]], 
      BoundaryStyle -> None, Axes -> False, Frame -> False] // Image //
     ImageCrop, d, pos}, d = ImageDimensions@rawpic;
 pos = Rasterize[
       Style["It's a lable", 25, Bold, FontFamily -> "Courier New"]] //
       Binarize // ImageData // Position[#, 0] & // 
   Round[{#[[1]] + d[[1]]*0.8, #[[2]] + d[[2]]*0.2}] & /@ # &;
 MapAt[1 - # &, ImageData[rawpic][[;; , ;; , ;; 3]], pos] // Image // 
  SetAlphaChannel[#, Binarize[#, 0.01]] &]

the effect is:

enter image description here

Is there a more convenient way to do it? The best is about how to use Style,and the result is a vectorgraph.Can Anybody give some suggstions?

$\endgroup$
2
  • $\begingroup$ I find this question vague as it is currently posed. What do you mean by "make the label text negate color"? What definition of "convenient" would you use to accept an answer? $\endgroup$
    – m_goldberg
    Sep 26 '15 at 6:37
  • $\begingroup$ "make the label text negate color" is negate to the label's background,the "convenient" is mean a better method no need to cope with the pixel in current solution.And I'm sorry for my poor English. $\endgroup$
    – yode
    Sep 26 '15 at 8:25
4
$\begingroup$

Using the code by MarcoB as a start and assuming that under "negate-color" you mean the result of applying ColorNegate:

plot = ParametricPlot[{x, y}, {x, 0, 1}, {y, 0, 1 - x}, 
   ColorFunction -> Function[{x, y}, RGBColor[x, y, 1 - x - y]], BoundaryStyle -> None, 
   Axes -> False, Frame -> False, PlotRangePadding -> None];
text = Graphics[{Inset[
     Style["It's a label", White, FontFamily -> "Arial", FontSize -> 32], 
     Scaled[{0.5, 0.2}]]}, Options[plot], Background -> Black];
i = ImageCompose[plot, 
  SetAlphaChannel[ColorNegate@ImageMultiply[Show[plot, Background -> Black], text], text]]

image

Assuming that you wish to have the text selectable after exporting to a vector format you can add completely transparent text over the raster version of the text - then after Exporting to PDF the text will be selectable:

i2 = Show[i, 
   Graphics[{Inset[
      Style["It's a label", Opacity[0.01], FontFamily -> "Arial", FontSize -> 32], 
      Scaled[{0.5, 0.2}]]}, Options[plot]]];

Export["i2.pdf", i2]

(I was forced to set Opacity[0.01] instead of Opacity[0] because with the latter the text is removed on Exporting - superfluously "smart" behavior of Export.)

Here is how the exported file looks in Adobe Acrobat when the text is selected:

screenshot


UPDATE

Here is completely vector-styled implementation without resorting to the tricks like transparent textual overlay.

At first we determine the positions of the characters in the image:

ps = ComponentMeasurements[Binarize[text, .95], "Centroid"];
Show[Image@text, 
 Epilog -> {Red, Table[Text[p[[1]], p[[2]], Background -> Yellow], {p, ps}]}]

plot

We see that the characters are counted non-sequentially, so we write the correct ordering by hands inserting zeros where the whitespace characters should be placed:

ordering = {1, 5, 2, 6, 0, 7, 0, 3, 8, 9, 10, 4};

Extract colors for the characters, negate them and apply the ordering:

colors = ColorNegate[RGBColor @@@ PixelValue[plot, ps[[;; , 2]]][[;; , ;; 3]]];
colorsSorted = colors[[ordering]];

Style the characters and combine everything together:

chs = Characters["It's a label"];
styledchs = 
  MapThread[Style[#1, #2, FontFamily -> "Arial", FontSize -> 32] /. 
     List :> (## &[]) &, {chs, colorsSorted}];
styledText = Graphics[Inset[Row[styledchs], Scaled[{0.5, 0.2}]]];
Show[plot, styledText]

plot

$\endgroup$
1
  • $\begingroup$ 1,(ordering = SortBy[ps, #[[2, 1]] &][[All, 1]];) 2,(chs = DeleteCases[Characters["It's a label"], " "];) All the way,your answer is very nice and your Opacity is so cute.Thanks a lot. $\endgroup$
    – yode
    Sep 26 '15 at 9:41
-1
$\begingroup$

Use Epilog to position an Inset containing appropriately Styled text wherever you want in the graph; a relative position is specified through a Scaled directive. Use PlotRangePadding-> None to eliminate the empty space around your figure.

ParametricPlot[{x, y}, {x, 0, 1}, {y, 0, 1 - x}, 
 ColorFunction -> Function[{x, y}, RGBColor[x, y, 1 - x - y]],
 BoundaryStyle -> None, Axes -> False, Frame -> False,

 (* new stuff *)
 PlotRangePadding -> None,
 Epilog -> Inset[
   Style["It's a label", White, FontFamily -> "Arial", FontSize -> 32],
   Scaled[{0.5, 0.2}]
  ]
]

Mathematica graphics

$\endgroup$
1
  • 1
    $\begingroup$ your label's color is constant white,which will not adapt to a negate color against background. $\endgroup$
    – yode
    Sep 26 '15 at 8:59

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.