Tikz pattern size in spy
Tikz pattern size in spy
I have a problem using pattern to fill shapes:
I've a shape thats filled with a self-defined pattern (simple dots with the same distance) and i want to zoom at one corner of the shape. I do this with spy (magnification=10).
Now inside the magnification the distance between the dots is the same as in the real picture, but i want them to be scaled also. Does anyone know how to do this?
Thanks for helping
documentclass[10pt,a4paper]article
usepackage[latin1]inputenc
usepackageamsmath
usepackageamsfonts
usepackageamssymb
usepackagegraphicx
usepackagetikz
usetikzlibraryarrows, plotmarks, patterns, spy
usepackagepgfplots
pgfdeclarepatternformonlydots-wide% name
pgfpointorigin% bottom left
pgfqpoint6mm6mm% top right
pgfqpoint6mm6mm% tile size
% code
pgfpathcirclepgfpoint0.3mm0.3mm0.3mm pgfusepathfill
pgfusepathfill
begindocument
begintikzpicture[spy using outlines=circle, magnification=10, connect spies, transform shape]
draw[pattern=dots-wide] (0,0) rectangle (3,3);
spy[size=5cm] on (2,2) in node at (8,2);
endtikzpicture
enddocument
documentclass...
enddocument
I can't reproduce the error, in the tikzEdt visor, but when I open in another pdf reader the error apears, A brute force solution could be drawing the patern manually using draw and foreach then use clip ...
– J Leon V.
Sep 3 at 17:59
I think it's no error... Just hopped someone knows a workaround
– Johannes Wendel
Sep 3 at 18:31
My common fallback for issues with spy is to use a standalone TikZ figure included as PDF. I then spy on the PDF includegraphics'ed inside a node.
– Daniel
Sep 3 at 20:07
1 Answer
1
I am not sure there is an elegant answer using patterns. This is because patterns are fast, but have certain pitfalls. The pgfmanual says in section 104.1:
There are a number of pitfalls and restrictions when using patterns.
First, once a pattern has been declared, you cannot change it anymore.
In particular, it is not possible to enlarge it or change the line
width. Such flexibility would require that the repeating of the
pattern were not done by the graphic language, but on the pgf level.
This would make patterns orders of magnitude slower to produce and to
render.
If you want to use spy, you may just resort to more conventional (but also much slower) methods to draw the dots. (There are many ways to make this more elegant, e.g. using a path picture
, but here I just present a rather clumsy workaround which will be shown in the next code.) In what follows I list some attempts that show that patterns are not transformed easily, and provide a first clumsy workaround.
path picture
documentclass[10pt,a4paper]article
usepackage[latin1]inputenc
usepackageamsmath
usepackageamsfonts
usepackageamssymb
usepackagetikz
usetikzlibraryarrows, plotmarks, patterns, spy
% made the pattern a bit more flexible but am not using it
pgfdeclarepatternformonly[dotradius,dotdistance]dots-wide% name
pgfpointorigin% bottom left
pgfqpointdotdistancedotdistance% top right
pgfqpointdotdistancedotdistance% tile size
% code
pgfpathcirclepgfpointdotradiusdotradiusdotradius pgfusepathfill
pgfusepathfill
tikzset
dot radius/.store in=dotradius,
dot radius=0.3mm,
dot distance/.store in=dotdistance,
dot distance=6mm
newsaveboxmybox
begindocument
section*Resistance of patterns against transformations
begintikzpicture[font=sffamily]
pattern [pattern=bricks] (-1,-1) rectangle (1,1);
node[anchor=south] at (0,1.1) original;
beginscope[xshift=3cm]
pattern [pattern=bricks,rotate=45] (-1,-1) rectangle (1,1);
node[anchor=south] at (0,1.4) ;
endscope
% these weird shifts are necessary because transform canvas is rather brutal
beginscope[xshift=cos(45)*8cm,yshift=-sin(45)*8cm,transform canvas=rotate=45]
pattern [pattern=bricks] (-1,-1) rectangle (1,1);
node[anchor=south,rotate=-45] at (1,1) transform canvas=rotate=45;
endscope
endtikzpicture
section*Not even saveboxes help
beginlrboxmybox%
begintikzpicture[font=sffamily]
pattern [pattern=bricks] (-1,-1) rectangle (1,1);
endtikzpicture%
endlrbox
begintikzpicture[font=sffamily]
node at (0,0)useboxmybox;
node[anchor=south] at (0,1.1) original;
beginscope[xshift=3cm]
node[rotate=45] at (0,0)useboxmybox;
node[anchor=south] at (0,1.4) ;
endscope
% these weird shifts are necessary because transform canvas is rather brutal
beginscope[xshift=cos(45)*8cm,yshift=-sin(45)*8cm,transform canvas=rotate=45]
node at (0,0)useboxmybox;
node[anchor=south,rotate=-45] at (1,1) transform canvas=rotate=45;
endscope
endtikzpicture
% section*Resistance of patterns against transformations
%
% begintikzpicture[font=sffamily]
% pattern [pattern=dots-wide] (-1,-1) rectangle (1,1);
% node[anchor=south] at (0,1.1) original;
% beginscope[xshift=3cm]
% pattern [pattern=dots-wide,rotate=45] (-1,-1) rectangle (1,1);
% node[anchor=south] at (0,1.4) ;
% endscope
% % these weird shifts are necessary because transform canvas is rather brutal
% beginscope[xshift=cos(45)*8cm,yshift=-sin(45)*8cm,transform canvas=rotate=45]
% pattern [pattern=dots-wide] (-1,-1) rectangle (1,1);
% node[anchor=south,rotate=-45] at (1,1) transform canvas=rotate=45;
% endscope
% endtikzpicture
%
% section*Not even saveboxes help
%
% beginlrboxmybox%
% begintikzpicture[font=sffamily]
% pattern [pattern=dots-wide] (-1,-1) rectangle (1,1);
% endtikzpicture%
% endlrbox
%
% begintikzpicture[font=sffamily]
% node at (0,0)useboxmybox;
% node[anchor=south] at (0,1.1) original;
% beginscope[xshift=3cm]
% node[rotate=45] at (0,0)useboxmybox;
% node[anchor=south] at (0,1.4) ;
% endscope
% % these weird shifts are necessary because transform canvas is rather brutal
% beginscope[xshift=cos(45)*8cm,yshift=-sin(45)*8cm,transform canvas=rotate=45]
% node at (0,0)useboxmybox;
% node[anchor=south,rotate=-45] at (1,1) transform canvas=rotate=45;
% endscope
% endtikzpicture
section*A workaround
begintikzpicture[spy using outlines=circle, magnification=10, connect spies, transform shape]
draw (0,0) rectangle (3,3);
foreach X in 0.3,0.9,...,2.7
foreach Y in 0.3,0.9,...,2.7
fill (X,Y) circle (0.3mm);
spy[size=5cm] on (2,2) in node at (8,2);
endtikzpicture
enddocument
This may, of course, be made much more elegant using path pictures
. I think one can redo any decoration that way. Arguably, it is even simpler to use that syntax, but the price one has to pay is performance. On the other hand, it is more straightforward to define the origin of the pattern. Another advantage of this is that it can be used in 3D projections. (I wish I would have known about this workaround when I created this... ;-) (EDIT: Got rid of the dangerous pgfextra
after learning that one can strip off the units with the function scalar
.)
path pictures
pgfextra
scalar
documentclassarticle
usepackagetikz
usetikzlibraryspy,calc
% these parameters can be adusted
tikzset
dot radius/.store in=dotradius,
dot radius=0.3mm,
dot distance/.store in=dotdistance,
dot distance=6mm
tikzsetdot pattern/.style=path picture=
fill let p1=($(path picture bounding box.north east)-(path picture bounding
box.south west)$), n1=int(scalar(x1/dotdistance))),
n2=int(scalar(y1/dotdistance)) in
foreach DotX in 1,...,n1
foreach DotY in 1,...,n2
($(path picture bounding box.south west)+((DotX-1/2)*dotdistance,
(DotY-1/2)*dotdistance)$) circle (dotradius)
;
begindocument
section*A slightly more elegant version of the workaround
begintikzpicture[spy using outlines=circle, magnification=10, connect spies, transform shape]
draw[dot pattern] (0,0) rectangle (3,3);
spy[size=5cm] on (2,2) in node at (8,2);
endtikzpicture
begintikzpicture[spy using outlines=circle, magnification=10, connect spies, transform shape]
draw[dot pattern] plot[smooth cycle] coordinates (0,0) (1,2) (3,3) (3,0)
(2,-1);
spy[size=5cm] on (2,1.5) in node at (8,2);
endtikzpicture
enddocument
Another workaround works as follows: create a pdf of pattern, and use it (with clip, say). Then you can zoom in without the need of a foreach loop. Make sure that you enable the externalization, e.g. by compiling with pdflatex -shell-escape
.
pdflatex -shell-escape
documentclassarticle
usepackagetikz
usetikzlibraryexternal
tikzexternalize
usetikzlibraryarrows, plotmarks, patterns, spy,external
% made the pattern a bit more flexible but am not using the flexibility here
pgfdeclarepatternformonly[dotradius,dotdistance]dots-wide% name
pgfpointorigin% bottom left
pgfqpointdotdistancedotdistance% top right
pgfqpointdotdistancedotdistance% tile size
% code
pgfpathcirclepgfpointdotradiusdotradiusdotradius pgfusepathfill
pgfusepathfill
tikzset
dot radius/.store in=dotradius,
dot radius=0.3mm,
dot distance/.store in=dotdistance,
dot distance=6mm
newsaveboxmybox
tikzexternalize
begindocument
% this is a trick to create some graphics without adding it to the document
% this trick is inspired by https://tex.stackexchange.com/a/433461/121799
beginlrboxmybox
tikzsetnextfilenamemypattern
begintikzpicture
fill [pattern=dots-wide] (-10,-10) rectangle (10,10);
endtikzpicture
endlrbox
tikzexternaldisable
section*Another workaround
begintikzpicture[spy using outlines=circle, magnification=10, connect spies, transform shape]
beginscope
draw[clip] (0,0) rectangle (3,3);
node at (0,0) includegraphicsmypattern.pdf;
endscope
spy[size=5cm] on (2,2) in node at (8,2);
endtikzpicture
enddocument
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
But avoid …
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Welcome to TeX.SX! Please help us help you and add a minimal working example (MWE) that illustrates your problem. Reproducing the problem and finding out what the issue is will be much easier when we see compilable code, starting with
documentclass...
and ending withenddocument
.– BambOo
Sep 3 at 17:10