I would like to create this chart. I know, I should provide something like a MWE but I don't have a clue where to start. I looked into all examples from the manual of pgfplots, but I did not see a single graph that culd be the start for this one. Is this possible? Could you help me create it? Thanks!
-
1I would search for https://tex.stackexchange.com/search?q=donut+chart. – Stefan Pinnow Jun 11 '19 at 20:12
-
see http://tex.stackexchange.com/questions/225949/. you can simplify proposed solutions. – Zarko Jun 11 '19 at 20:14
2 Answers
Among the already existing solutions the one that I found to come closest to your screen shot is perhaps this answer. Here is a version that is somewhat similar in approach but uses a pic instead of a macro. The reason why I am posting it is that this one can be transformed easily (and the line width gets transformed, too, which is why there is this cryptic \pgfgettransformentries...). So you need only to say
\path (0,0) pic[scale=5,donut/offset=90]{donut=26};
to get
Here is the code with this and additional examples. There are several options that I tried to include. The recently added options are clockwise and bar (for Stefan Pinnow). The `bar option was a bit more "nasty" to implement since I did not want just to draw a white line, which would backfire if there is a nontrivial background, or one wants to adjust the opacity.
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc}
% from https://tex.stackexchange.com/a/76216/121799
\tikzset{clip even odd rule/.code={\pgfseteorule}}
\begin{document}
\begin{tikzpicture}[
pics/donut/.style={
code={
\node[
font=\sffamily\bfseries,
text=\pgfkeysvalueof{/tikz/donut/fg},
transform shape,
circle,
/tikz/donut/donut node,
] (dn) {#1\%};
\pgfgettransformentries{\myx}{\tmp}{\tmp}{\tmp}{\tmp}{\tmp}
%
\ifdim\pgfkeysvalueof{/tikz/donut/bar width}>0pt
\clip [clip even odd rule] let
\p1=($(dn.north) - (dn.center)$),
\n1={veclen(\x1,\y1)},
\n2={\n1 + \pgfkeysvalueof{/tikz/donut/line width}}
in
(0,0) circle [radius=0.99*\n1]
(0,0) circle [radius=1.01*\n2]
($(\pgfkeysvalueof{/tikz/donut/direction}*\pgfkeysvalueof{/tikz/donut/offset}:0.8*\n1)+({\pgfkeysvalueof{/tikz/donut/direction}*\pgfkeysvalueof{/tikz/donut/offset}+90}:\pgfkeysvalueof{/tikz/donut/direction}*\pgfkeysvalueof{/tikz/donut/bar width}/2)$)
-- ++
({\pgfkeysvalueof{/tikz/donut/direction}*\pgfkeysvalueof{/tikz/donut/offset}}:2.5*\pgfkeysvalueof{/tikz/donut/line width})
-- ++
({\pgfkeysvalueof{/tikz/donut/direction}*(\pgfkeysvalueof{/tikz/donut/offset}-90)}:\pgfkeysvalueof{/tikz/donut/bar width})
-- ++
({\pgfkeysvalueof{/tikz/donut/direction}*(\pgfkeysvalueof{/tikz/donut/offset}+180)}:2.5*\pgfkeysvalueof{/tikz/donut/line width})
-- cycle
%
($({\pgfkeysvalueof{/tikz/donut/direction}*(\pgfkeysvalueof{/tikz/donut/offset}+#1*3.6)}:0.8*\n1)+
({\pgfkeysvalueof{/tikz/donut/direction}*(\pgfkeysvalueof{/tikz/donut/offset}+90+#1*3.6)}:\pgfkeysvalueof{/tikz/donut/bar width}/2)$)
-- ++
({\pgfkeysvalueof{/tikz/donut/direction}*(\pgfkeysvalueof{/tikz/donut/offset}+#1*3.6)}:2.5*\pgfkeysvalueof{/tikz/donut/line width})
-- ++
({\pgfkeysvalueof{/tikz/donut/direction}*(\pgfkeysvalueof{/tikz/donut/offset}+#1*3.6-90)}:\pgfkeysvalueof{/tikz/donut/bar width})
-- ++
({\pgfkeysvalueof{/tikz/donut/direction}*(\pgfkeysvalueof{/tikz/donut/offset}+#1*3.6+180)}:2.5*\pgfkeysvalueof{/tikz/donut/line width})
-- cycle
;
\fi
%
\draw [
color=\pgfkeysvalueof{/tikz/donut/fg},
line width=\myx * \pgfkeysvalueof{/tikz/donut/line width}
] let
\p1=($(dn.north) - (dn.center)$),
\n1={
veclen(\x1,\y1) + 0.5*\pgfkeysvalueof{/tikz/donut/line width}
}
in ({\pgfkeysvalueof{/tikz/donut/direction}*(
\pgfkeysvalueof{/tikz/donut/deficit}
+ \pgfkeysvalueof{/tikz/donut/offset})}:\n1)
arc ({\pgfkeysvalueof{/tikz/donut/direction}*(
\pgfkeysvalueof{/tikz/donut/deficit}
+ \pgfkeysvalueof{/tikz/donut/offset})}:{
\pgfkeysvalueof{/tikz/donut/direction}*(3.6*#1
+ \pgfkeysvalueof{/tikz/donut/offset}
- \pgfkeysvalueof{/tikz/donut/deficit})}:\n1);
\draw[
color=\pgfkeysvalueof{/tikz/donut/bg},
line width=\myx*\pgfkeysvalueof{/tikz/donut/line width}
] let
\p1=($(dn.north) - (dn.center)$),
\n1={
veclen(\x1,\y1) + 0.5*\pgfkeysvalueof{/tikz/donut/line width}
}
in ({\pgfkeysvalueof{/tikz/donut/direction}*(
3.6*#1
+\pgfkeysvalueof{/tikz/donut/deficit}
+\pgfkeysvalueof{/tikz/donut/offset})}:\n1
)
arc ({\pgfkeysvalueof{/tikz/donut/direction}*(3.6*#1
+ \pgfkeysvalueof{/tikz/donut/deficit}
+ \pgfkeysvalueof{/tikz/donut/offset})}:{
\pgfkeysvalueof{/tikz/donut/direction}*(360
+ \pgfkeysvalueof{/tikz/donut/offset}
- \pgfkeysvalueof{/tikz/donut/deficit})}:\n1
);
},
},
donut/.cd,
fg/.initial=orange,
bg/.initial=gray!40,
line width/.initial=3mm,
deficit/.initial=2,
donut node/.style={},
offset/.initial=0,
direction/.initial=1,
bar width/.initial=0pt,
clockwise/.code=\tikzset{donut/direction=-1},
bar/.code=\tikzset{donut/deficit=0pt,donut/bar width=#1}
]
\path
(0,0) pic [scale=5,donut/offset=90] {donut=26}
(8,0) pic [scale=3,donut/clockwise] {donut=87}
(0,-8) pic [scale=3,donut/.cd,fg=blue,bg=yellow,
donut node/.style={inner sep=1pt}] {donut=38}
(8,-8) pic [scale=3,donut/.cd,
fg=red,bg=yellow,clockwise,
bar=1mm, offset=200] {donut=38.7346}
(0,-16) pic [scale=3,donut/.cd, clockwise,bar=1mm,offset=270] {donut=56}
(8,-16) pic [scale=3,donut/.cd,bar=1mm, offset=200] {donut=76}
;
\end{tikzpicture}
\end{document}
-
Wow, that looks good! (And complicated...). Ome simple question: is it possible to make the starting point in the north, instead of ending in east? – spectre Jun 11 '19 at 21:14
-
1@spectre Sure. I added an offset parameter. (This is the advantage of pgf keys over proposals that have been advertized as "simplified" in the above comments. With pgf keys you can always add keys wile keeping the code downwards compatible, which is why cfr's answer, various other posts and this answer use them.) – Jun 11 '19 at 21:25
-
And do you have an inverse option? Thus start at 0 (I can do now with the offset) and then moving clockwise instead of the default counter-clockwise – spectre Jun 11 '19 at 21:31
-
@spectre Sure, this is easy to do but it is not the purpose of this site that someone converts your instructions into LaTeX code. The above, and many other codes mentioned in the above comments, give you enough information to accomplish whatever you want to achieve. If you have concrete problems making a code that you developed from some starting point do what you want, you will have a good basis for a question that will be answered here. But I am not going to carry out your instructions. – Jun 11 '19 at 21:39
-
I understand, thanks for your great example. I’ll try this week if I’m able to understand the code and add a inverse key – spectre Jun 11 '19 at 21:43
-
1@marmot, great work again. Hopefully you don't mind that I reformatted your code thus it is more readable. But still after a quick look I am not sure what does what. Maybe you add some comments to the code? – Stefan Pinnow Jun 12 '19 at 04:25
-
And maybe you are able to introduce one more improvement to the code. When you compare the image of OP and the result of your "26%" donut you may recognize that the gab between the segments in OPs image seems to have a constant width while in your image the gab increases with increasing radius. Any ideas for that? – Stefan Pinnow Jun 12 '19 at 04:28
-
1@StefanPinnow Thanks! Wait, then everyone can write such code? Just kidding! (My text editor makes it sort of possible to read the code, but I agree that does not help others who read it here.) I will add these modifications. – Jun 12 '19 at 04:29
-
@StefanPinnow This was slightly more "nasty" because I did not just want to draw a white line. – Jun 12 '19 at 05:27
-
2@marmot, awesome. Unfortunately I cannot upvote again ... Hopefully you didn't mind (again) that I did minor changes to your code. The most relavant change is changing the change to
bar=1mmof the last donut. In my opinion this issue is mostly relevant for small gabs when the wedge is clearly visible. – Stefan Pinnow Jun 12 '19 at 06:14 -
@StefanPinnow, I see a problem in the resulting graph if I apply the combination of offset and bar; for example, bar=1mm, offset=270 (which I want) but it is more clear with bar=1mm, offset=200 then something weird happens. Can you help me solving this one? – spectre Jun 13 '19 at 06:37
-
-
@marmot, thanks again! There was still a small bug to the bar if the picture was clockwise. I believe it was because the direction key was not applied somewhere, I added this to the code. – spectre Jun 13 '19 at 07:59
-
@spectre Your edit was rejected. Please tell me what you wanted to edit and why such that I can add it. – Jun 13 '19 at 15:12
-
1@marmot: if I use the clockwise option together with a bar, the starting white bar is not painting correclty: it is a little bit shifted to the wrong side. this is clear with an option like
pic [scale=3,donut/.cd, clockwise,bar=1mm,offset=270] donut=2};This is caused because in one of the calculations, the direction is not incorporated. It is in the line directly after
– spectre Jun 13 '19 at 15:40(0,0) circle [radius=1.01*\n2]. If you change the part(\pgfkeysvalueof{/tikz/donut/offset}+90to(\pgfkeysvalueof{/tikz/donut/direction}*\pgfkeysvalueof{/tikz/donut/offset}+90, it is fixed. -
With wheelchart package:
\documentclass[tikz, border=2mm]{standalone}
\usepackage{wheelchart}
\usepackage[detect-all]{siunitx}
\usepackage{lmodern}
\begin{document}
\def\n{26}
\begin{tikzpicture}[font=\sffamily\bfseries]
\wheelchart[
data={},
gap polar,
middle={\Huge\qty{\n}{\percent}},
]{\n/orange,{100-\n}/gray}
\end{tikzpicture}
\end{document}
- 136,588



