Skip to content

Instantly share code, notes, and snippets.

@epilys
Last active June 10, 2021 16:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save epilys/4df67027dc5db661969b086bac56385f to your computer and use it in GitHub Desktop.
Save epilys/4df67027dc5db661969b086bac56385f to your computer and use it in GitHub Desktop.
Draw treemap with hatch patterns in vanilla matplotlib + python3. It can be easily modified to use colors instead of hatches.
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Created with matplotlib (https://matplotlib.org/) -->
<svg height="345.6pt" version="1.1" viewBox="0 0 460.8 345.6" width="460.8pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<metadata>
<rdf:RDF xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:date>2021-06-10T19:23:32.758187</dc:date>
<dc:format>image/svg+xml</dc:format>
<dc:creator>
<cc:Agent>
<dc:title>Matplotlib v3.3.3, https://matplotlib.org/</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
</rdf:RDF>
</metadata>
<defs>
<style type="text/css">*{stroke-linecap:butt;stroke-linejoin:round;}</style>
</defs>
<g id="figure_1">
<g id="patch_1">
<path d="M 0 345.6
L 460.8 345.6
L 460.8 0
L 0 0
z
" style="fill:#ffffff;"/>
</g>
<g id="axes_1">
<g id="patch_2">
<path d="M 57.6 345.6
L 403.2 345.6
L 403.2 0
L 57.6 0
z
" style="fill:#ffffff;"/>
</g>
<g id="patch_3">
<path clip-path="url(#p41b2d4575b)" d="M 57.6 345.6
L 403.2 345.6
L 403.2 0
L 57.6 0
z
" style="fill:none;stroke:#000000;stroke-linejoin:miter;"/>
</g>
<g id="patch_4">
<path clip-path="url(#p41b2d4575b)" d="M 57.6 345.6
L 238.164263 345.6
L 238.164263 0
L 57.6 0
z
" style="fill:url(#haa47c07400);stroke:#000000;stroke-linejoin:miter;"/>
</g>
<g id="patch_5">
<path clip-path="url(#p41b2d4575b)" d="M 238.164263 345.6
L 294.500313 345.6
L 294.500313 0
L 238.164263 0
z
" style="fill:url(#hfc7ffd181e);stroke:#000000;stroke-linejoin:miter;"/>
</g>
<g id="patch_6">
<path clip-path="url(#p41b2d4575b)" d="M 294.500313 345.6
L 403.2 345.6
L 403.2 0
L 294.500313 0
z
" style="fill:url(#ha7c7b034f8);stroke:#000000;stroke-linejoin:miter;"/>
</g>
<g id="matplotlib.axis_1">
<g id="text_1">
<!-- tree (500, 156, 301) -->
<g transform="translate(179.865625 357.198437)scale(0.1 -0.1)">
<defs>
<path d="M 18.3125 70.21875
L 18.3125 54.6875
L 36.8125 54.6875
L 36.8125 47.703125
L 18.3125 47.703125
L 18.3125 18.015625
Q 18.3125 11.328125 20.140625 9.421875
Q 21.96875 7.515625 27.59375 7.515625
L 36.8125 7.515625
L 36.8125 0
L 27.59375 0
Q 17.1875 0 13.234375 3.875
Q 9.28125 7.765625 9.28125 18.015625
L 9.28125 47.703125
L 2.6875 47.703125
L 2.6875 54.6875
L 9.28125 54.6875
L 9.28125 70.21875
z
" id="DejaVuSans-116"/>
<path d="M 41.109375 46.296875
Q 39.59375 47.171875 37.8125 47.578125
Q 36.03125 48 33.890625 48
Q 26.265625 48 22.1875 43.046875
Q 18.109375 38.09375 18.109375 28.8125
L 18.109375 0
L 9.078125 0
L 9.078125 54.6875
L 18.109375 54.6875
L 18.109375 46.1875
Q 20.953125 51.171875 25.484375 53.578125
Q 30.03125 56 36.53125 56
Q 37.453125 56 38.578125 55.875
Q 39.703125 55.765625 41.0625 55.515625
z
" id="DejaVuSans-114"/>
<path d="M 56.203125 29.59375
L 56.203125 25.203125
L 14.890625 25.203125
Q 15.484375 15.921875 20.484375 11.0625
Q 25.484375 6.203125 34.421875 6.203125
Q 39.59375 6.203125 44.453125 7.46875
Q 49.3125 8.734375 54.109375 11.28125
L 54.109375 2.78125
Q 49.265625 0.734375 44.1875 -0.34375
Q 39.109375 -1.421875 33.890625 -1.421875
Q 20.796875 -1.421875 13.15625 6.1875
Q 5.515625 13.8125 5.515625 26.8125
Q 5.515625 40.234375 12.765625 48.109375
Q 20.015625 56 32.328125 56
Q 43.359375 56 49.78125 48.890625
Q 56.203125 41.796875 56.203125 29.59375
z
M 47.21875 32.234375
Q 47.125 39.59375 43.09375 43.984375
Q 39.0625 48.390625 32.421875 48.390625
Q 24.90625 48.390625 20.390625 44.140625
Q 15.875 39.890625 15.1875 32.171875
z
" id="DejaVuSans-101"/>
<path id="DejaVuSans-32"/>
<path d="M 31 75.875
Q 24.46875 64.65625 21.28125 53.65625
Q 18.109375 42.671875 18.109375 31.390625
Q 18.109375 20.125 21.3125 9.0625
Q 24.515625 -2 31 -13.1875
L 23.1875 -13.1875
Q 15.875 -1.703125 12.234375 9.375
Q 8.59375 20.453125 8.59375 31.390625
Q 8.59375 42.28125 12.203125 53.3125
Q 15.828125 64.359375 23.1875 75.875
z
" id="DejaVuSans-40"/>
<path d="M 10.796875 72.90625
L 49.515625 72.90625
L 49.515625 64.59375
L 19.828125 64.59375
L 19.828125 46.734375
Q 21.96875 47.46875 24.109375 47.828125
Q 26.265625 48.1875 28.421875 48.1875
Q 40.625 48.1875 47.75 41.5
Q 54.890625 34.8125 54.890625 23.390625
Q 54.890625 11.625 47.5625 5.09375
Q 40.234375 -1.421875 26.90625 -1.421875
Q 22.3125 -1.421875 17.546875 -0.640625
Q 12.796875 0.140625 7.71875 1.703125
L 7.71875 11.625
Q 12.109375 9.234375 16.796875 8.0625
Q 21.484375 6.890625 26.703125 6.890625
Q 35.15625 6.890625 40.078125 11.328125
Q 45.015625 15.765625 45.015625 23.390625
Q 45.015625 31 40.078125 35.4375
Q 35.15625 39.890625 26.703125 39.890625
Q 22.75 39.890625 18.8125 39.015625
Q 14.890625 38.140625 10.796875 36.28125
z
" id="DejaVuSans-53"/>
<path d="M 31.78125 66.40625
Q 24.171875 66.40625 20.328125 58.90625
Q 16.5 51.421875 16.5 36.375
Q 16.5 21.390625 20.328125 13.890625
Q 24.171875 6.390625 31.78125 6.390625
Q 39.453125 6.390625 43.28125 13.890625
Q 47.125 21.390625 47.125 36.375
Q 47.125 51.421875 43.28125 58.90625
Q 39.453125 66.40625 31.78125 66.40625
z
M 31.78125 74.21875
Q 44.046875 74.21875 50.515625 64.515625
Q 56.984375 54.828125 56.984375 36.375
Q 56.984375 17.96875 50.515625 8.265625
Q 44.046875 -1.421875 31.78125 -1.421875
Q 19.53125 -1.421875 13.0625 8.265625
Q 6.59375 17.96875 6.59375 36.375
Q 6.59375 54.828125 13.0625 64.515625
Q 19.53125 74.21875 31.78125 74.21875
z
" id="DejaVuSans-48"/>
<path d="M 11.71875 12.40625
L 22.015625 12.40625
L 22.015625 4
L 14.015625 -11.625
L 7.71875 -11.625
L 11.71875 4
z
" id="DejaVuSans-44"/>
<path d="M 12.40625 8.296875
L 28.515625 8.296875
L 28.515625 63.921875
L 10.984375 60.40625
L 10.984375 69.390625
L 28.421875 72.90625
L 38.28125 72.90625
L 38.28125 8.296875
L 54.390625 8.296875
L 54.390625 0
L 12.40625 0
z
" id="DejaVuSans-49"/>
<path d="M 33.015625 40.375
Q 26.375 40.375 22.484375 35.828125
Q 18.609375 31.296875 18.609375 23.390625
Q 18.609375 15.53125 22.484375 10.953125
Q 26.375 6.390625 33.015625 6.390625
Q 39.65625 6.390625 43.53125 10.953125
Q 47.40625 15.53125 47.40625 23.390625
Q 47.40625 31.296875 43.53125 35.828125
Q 39.65625 40.375 33.015625 40.375
z
M 52.59375 71.296875
L 52.59375 62.3125
Q 48.875 64.0625 45.09375 64.984375
Q 41.3125 65.921875 37.59375 65.921875
Q 27.828125 65.921875 22.671875 59.328125
Q 17.53125 52.734375 16.796875 39.40625
Q 19.671875 43.65625 24.015625 45.921875
Q 28.375 48.1875 33.59375 48.1875
Q 44.578125 48.1875 50.953125 41.515625
Q 57.328125 34.859375 57.328125 23.390625
Q 57.328125 12.15625 50.6875 5.359375
Q 44.046875 -1.421875 33.015625 -1.421875
Q 20.359375 -1.421875 13.671875 8.265625
Q 6.984375 17.96875 6.984375 36.375
Q 6.984375 53.65625 15.1875 63.9375
Q 23.390625 74.21875 37.203125 74.21875
Q 40.921875 74.21875 44.703125 73.484375
Q 48.484375 72.75 52.59375 71.296875
z
" id="DejaVuSans-54"/>
<path d="M 40.578125 39.3125
Q 47.65625 37.796875 51.625 33
Q 55.609375 28.21875 55.609375 21.1875
Q 55.609375 10.40625 48.1875 4.484375
Q 40.765625 -1.421875 27.09375 -1.421875
Q 22.515625 -1.421875 17.65625 -0.515625
Q 12.796875 0.390625 7.625 2.203125
L 7.625 11.71875
Q 11.71875 9.328125 16.59375 8.109375
Q 21.484375 6.890625 26.8125 6.890625
Q 36.078125 6.890625 40.9375 10.546875
Q 45.796875 14.203125 45.796875 21.1875
Q 45.796875 27.640625 41.28125 31.265625
Q 36.765625 34.90625 28.71875 34.90625
L 20.21875 34.90625
L 20.21875 43.015625
L 29.109375 43.015625
Q 36.375 43.015625 40.234375 45.921875
Q 44.09375 48.828125 44.09375 54.296875
Q 44.09375 59.90625 40.109375 62.90625
Q 36.140625 65.921875 28.71875 65.921875
Q 24.65625 65.921875 20.015625 65.03125
Q 15.375 64.15625 9.8125 62.3125
L 9.8125 71.09375
Q 15.4375 72.65625 20.34375 73.4375
Q 25.25 74.21875 29.59375 74.21875
Q 40.828125 74.21875 47.359375 69.109375
Q 53.90625 64.015625 53.90625 55.328125
Q 53.90625 49.265625 50.4375 45.09375
Q 46.96875 40.921875 40.578125 39.3125
z
" id="DejaVuSans-51"/>
<path d="M 8.015625 75.875
L 15.828125 75.875
Q 23.140625 64.359375 26.78125 53.3125
Q 30.421875 42.28125 30.421875 31.390625
Q 30.421875 20.453125 26.78125 9.375
Q 23.140625 -1.703125 15.828125 -13.1875
L 8.015625 -13.1875
Q 14.5 -2 17.703125 9.0625
Q 20.90625 20.125 20.90625 31.390625
Q 20.90625 42.671875 17.703125 53.65625
Q 14.5 64.65625 8.015625 75.875
z
" id="DejaVuSans-41"/>
</defs>
<use xlink:href="#DejaVuSans-116"/>
<use x="39.208984" xlink:href="#DejaVuSans-114"/>
<use x="78.072266" xlink:href="#DejaVuSans-101"/>
<use x="139.595703" xlink:href="#DejaVuSans-101"/>
<use x="201.119141" xlink:href="#DejaVuSans-32"/>
<use x="232.90625" xlink:href="#DejaVuSans-40"/>
<use x="271.919922" xlink:href="#DejaVuSans-53"/>
<use x="335.542969" xlink:href="#DejaVuSans-48"/>
<use x="399.166016" xlink:href="#DejaVuSans-48"/>
<use x="462.789062" xlink:href="#DejaVuSans-44"/>
<use x="494.576172" xlink:href="#DejaVuSans-32"/>
<use x="526.363281" xlink:href="#DejaVuSans-49"/>
<use x="589.986328" xlink:href="#DejaVuSans-53"/>
<use x="653.609375" xlink:href="#DejaVuSans-54"/>
<use x="717.232422" xlink:href="#DejaVuSans-44"/>
<use x="749.019531" xlink:href="#DejaVuSans-32"/>
<use x="780.806641" xlink:href="#DejaVuSans-51"/>
<use x="844.429688" xlink:href="#DejaVuSans-48"/>
<use x="908.052734" xlink:href="#DejaVuSans-49"/>
<use x="971.675781" xlink:href="#DejaVuSans-41"/>
</g>
</g>
</g>
<g id="matplotlib.axis_2"/>
<g id="patch_7">
<path d="M 57.6 345.6
L 57.6 0
" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/>
</g>
<g id="patch_8">
<path d="M 403.2 345.6
L 403.2 0
" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/>
</g>
<g id="patch_9">
<path d="M 57.6 345.6
L 403.2 345.6
" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/>
</g>
<g id="patch_10">
<path d="M 57.6 0
L 403.2 0
" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/>
</g>
<g id="text_2">
<g id="patch_11">
<path d="M 134.889085 180.755156
L 160.875179 180.755156
L 160.875179 164.844844
L 134.889085 164.844844
z
" style="fill:#ffffff;stroke:#ffffff;stroke-linejoin:miter;"/>
</g>
<!-- 500 -->
<g transform="translate(138.489085 175.283437)scale(0.09 -0.09)">
<defs>
<path d="M 10.59375 72.90625
L 57.328125 72.90625
L 57.328125 59.078125
L 25.59375 59.078125
L 25.59375 47.796875
Q 27.734375 48.390625 29.90625 48.703125
Q 32.078125 49.03125 34.421875 49.03125
Q 47.75 49.03125 55.171875 42.359375
Q 62.59375 35.6875 62.59375 23.78125
Q 62.59375 11.96875 54.515625 5.265625
Q 46.4375 -1.421875 32.078125 -1.421875
Q 25.875 -1.421875 19.796875 -0.21875
Q 13.71875 0.984375 7.71875 3.421875
L 7.71875 18.21875
Q 13.671875 14.796875 19.015625 13.078125
Q 24.359375 11.375 29.109375 11.375
Q 35.9375 11.375 39.859375 14.71875
Q 43.796875 18.0625 43.796875 23.78125
Q 43.796875 29.546875 39.859375 32.859375
Q 35.9375 36.1875 29.109375 36.1875
Q 25.046875 36.1875 20.453125 35.125
Q 15.875 34.078125 10.59375 31.890625
z
" id="DejaVuSans-Bold-53"/>
<path d="M 46 36.53125
Q 46 50.203125 43.4375 55.78125
Q 40.875 61.375 34.8125 61.375
Q 28.765625 61.375 26.171875 55.78125
Q 23.578125 50.203125 23.578125 36.53125
Q 23.578125 22.703125 26.171875 17.03125
Q 28.765625 11.375 34.8125 11.375
Q 40.828125 11.375 43.40625 17.03125
Q 46 22.703125 46 36.53125
z
M 64.796875 36.375
Q 64.796875 18.265625 56.984375 8.421875
Q 49.171875 -1.421875 34.8125 -1.421875
Q 20.40625 -1.421875 12.59375 8.421875
Q 4.78125 18.265625 4.78125 36.375
Q 4.78125 54.546875 12.59375 64.375
Q 20.40625 74.21875 34.8125 74.21875
Q 49.171875 74.21875 56.984375 64.375
Q 64.796875 54.546875 64.796875 36.375
z
" id="DejaVuSans-Bold-48"/>
</defs>
<use xlink:href="#DejaVuSans-Bold-53"/>
<use x="69.580078" xlink:href="#DejaVuSans-Bold-48"/>
<use x="139.160156" xlink:href="#DejaVuSans-Bold-48"/>
</g>
</g>
<g id="text_3">
<g id="patch_12">
<path d="M 253.339242 180.755156
L 279.325335 180.755156
L 279.325335 164.844844
L 253.339242 164.844844
z
" style="fill:#ffffff;stroke:#ffffff;stroke-linejoin:miter;"/>
</g>
<!-- 156 -->
<g transform="translate(256.939242 175.283437)scale(0.09 -0.09)">
<defs>
<path d="M 11.71875 12.984375
L 28.328125 12.984375
L 28.328125 60.109375
L 11.28125 56.59375
L 11.28125 69.390625
L 28.21875 72.90625
L 46.09375 72.90625
L 46.09375 12.984375
L 62.703125 12.984375
L 62.703125 0
L 11.71875 0
z
" id="DejaVuSans-Bold-49"/>
<path d="M 36.1875 35.984375
Q 31.25 35.984375 28.78125 32.78125
Q 26.3125 29.59375 26.3125 23.1875
Q 26.3125 16.796875 28.78125 13.59375
Q 31.25 10.40625 36.1875 10.40625
Q 41.15625 10.40625 43.625 13.59375
Q 46.09375 16.796875 46.09375 23.1875
Q 46.09375 29.59375 43.625 32.78125
Q 41.15625 35.984375 36.1875 35.984375
z
M 59.421875 71
L 59.421875 57.515625
Q 54.78125 59.71875 50.671875 60.765625
Q 46.578125 61.8125 42.671875 61.8125
Q 34.28125 61.8125 29.59375 57.140625
Q 24.90625 52.484375 24.125 43.3125
Q 27.34375 45.703125 31.09375 46.890625
Q 34.859375 48.09375 39.3125 48.09375
Q 50.484375 48.09375 57.34375 41.546875
Q 64.203125 35.015625 64.203125 24.421875
Q 64.203125 12.703125 56.53125 5.640625
Q 48.875 -1.421875 35.984375 -1.421875
Q 21.78125 -1.421875 13.984375 8.171875
Q 6.203125 17.78125 6.203125 35.40625
Q 6.203125 53.46875 15.3125 63.796875
Q 24.421875 74.125 40.28125 74.125
Q 45.3125 74.125 50.046875 73.34375
Q 54.78125 72.5625 59.421875 71
z
" id="DejaVuSans-Bold-54"/>
</defs>
<use xlink:href="#DejaVuSans-Bold-49"/>
<use x="69.580078" xlink:href="#DejaVuSans-Bold-53"/>
<use x="139.160156" xlink:href="#DejaVuSans-Bold-54"/>
</g>
</g>
<g id="text_4">
<g id="patch_13">
<path d="M 335.85711 180.755156
L 361.843204 180.755156
L 361.843204 164.844844
L 335.85711 164.844844
z
" style="fill:#ffffff;stroke:#ffffff;stroke-linejoin:miter;"/>
</g>
<!-- 301 -->
<g transform="translate(339.45711 175.283437)scale(0.09 -0.09)">
<defs>
<path d="M 46.578125 39.3125
Q 53.953125 37.40625 57.78125 32.6875
Q 61.625 27.984375 61.625 20.703125
Q 61.625 9.859375 53.3125 4.21875
Q 45.015625 -1.421875 29.109375 -1.421875
Q 23.484375 -1.421875 17.84375 -0.515625
Q 12.203125 0.390625 6.6875 2.203125
L 6.6875 16.703125
Q 11.96875 14.0625 17.15625 12.71875
Q 22.359375 11.375 27.390625 11.375
Q 34.859375 11.375 38.84375 13.953125
Q 42.828125 16.546875 42.828125 21.390625
Q 42.828125 26.375 38.75 28.9375
Q 34.671875 31.5 26.703125 31.5
L 19.1875 31.5
L 19.1875 43.609375
L 27.09375 43.609375
Q 34.1875 43.609375 37.640625 45.828125
Q 41.109375 48.046875 41.109375 52.59375
Q 41.109375 56.78125 37.734375 59.078125
Q 34.375 61.375 28.21875 61.375
Q 23.6875 61.375 19.046875 60.34375
Q 14.40625 59.328125 9.8125 57.328125
L 9.8125 71.09375
Q 15.375 72.65625 20.84375 73.4375
Q 26.3125 74.21875 31.59375 74.21875
Q 45.796875 74.21875 52.84375 69.546875
Q 59.90625 64.890625 59.90625 55.515625
Q 59.90625 49.125 56.53125 45.046875
Q 53.171875 40.96875 46.578125 39.3125
z
" id="DejaVuSans-Bold-51"/>
</defs>
<use xlink:href="#DejaVuSans-Bold-51"/>
<use x="69.580078" xlink:href="#DejaVuSans-Bold-48"/>
<use x="139.160156" xlink:href="#DejaVuSans-Bold-49"/>
</g>
</g>
</g>
</g>
<defs>
<clipPath id="p41b2d4575b">
<rect height="345.6" width="345.6" x="57.6" y="0"/>
</clipPath>
</defs>
<defs>
<pattern height="72" id="haa47c07400" patternUnits="userSpaceOnUse" width="72" x="0" y="0">
<rect fill="none" height="73" width="73" x="0" y="0"/>
<path d="M -36 36
L 36 -36
M -24 48
L 48 -24
M -12 60
L 60 -12
M 0 72
L 72 0
M 12 84
L 84 12
M 24 96
L 96 24
M 36 108
L 108 36
" style="fill:#000000;stroke:#000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-width:0.9;"/>
</pattern>
<pattern height="72" id="hfc7ffd181e" patternUnits="userSpaceOnUse" width="72" x="0" y="0">
<rect fill="none" height="73" width="73" x="0" y="0"/>
<path d="M -36 36
L 36 108
M -24 24
L 48 96
M -12 12
L 60 84
M 0 0
L 72 72
M 12 -12
L 84 60
M 24 -24
L 96 48
M 36 -36
L 108 36
" style="fill:#000000;stroke:#000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-width:0.9;"/>
</pattern>
<pattern height="72" id="ha7c7b034f8" patternUnits="userSpaceOnUse" width="72" x="0" y="0">
<rect fill="none" height="73" width="73" x="0" y="0"/>
<path d="M 6 72
L 6 0
M 18 72
L 18 0
M 30 72
L 30 0
M 42 72
L 42 0
M 54 72
L 54 0
M 66 72
L 66 0
" style="fill:#000000;stroke:#000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-width:0.9;"/>
</pattern>
</defs>
</svg>
import matplotlib
matplotlib.rcParams["hatch.linewidth"] = 0.9
from matplotlib import pylab
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from functools import reduce
import io
# Hatch reference: https://matplotlib.org/stable/gallery/shapes_and_collections/hatch_style_reference.html#sphx-glr-gallery-shapes-and-collections-hatch-style-reference-py
# Doubling the size of a string (i.e. '+'*2) makes the hatches thicker
# Use matplotlib.rcParams['hatch.linewidth'] to set the linewidth
def hatches():
list_ = ["/", "\\", "|", "-", "+", "x", "o", "O", ".", "*"]
i = 0
wraps = 0
while True:
index = i % len(list_)
yield list_[i] * (wraps + 1)
i = i + 1
if i >= len(list_):
i -= len(list_)
wraps += 1
"""
Code adapted from https://scipy-cookbook.readthedocs.io/items/Matplotlib_TreeMap.html
"""
class Treemap:
"""
Treemap builder using pylab.
Uses algorithm straight from http://hcil.cs.umd.edu/trs/91-03/91-03.html
James Casbon 29/7/2006
"""
def __init__(self, title, tree, labels):
"""example trees:
tree= ((5,(3,5)), 4, (5,2,(2,3,(3,2,2)),(3,3)), (3,2) )
tree = ((6, 5))
"""
self.done = False
self.hatches_gen = hatches()
self.tree = tree
self.labels = labels
self.title = title
def compute(self):
def new_size_method():
size_cache = {}
def _size(thing):
if isinstance(thing, int):
return thing
if thing in size_cache:
return size_cache[thing]
else:
size_cache[thing] = reduce(int.__add__, [_size(x) for x in thing])
return size_cache[thing]
return _size
self.size_method = new_size_method()
self.ax = pylab.subplot(111, aspect="equal")
pylab.subplots_adjust(left=0, right=1, top=1, bottom=0)
self.ax.set_xticks([])
self.ax.set_yticks([])
self.iter_method = iter
self.rectangles = []
self.addnode(self.tree, lower=[0, 0], upper=[1, 1], axis=0)
i = 0
for (n, r) in self.rectangles:
if isinstance(n, int):
label = str(self.labels[i])
i += 1
rx, ry = r.get_xy()
cx = rx + r.get_width() / 2.0
cy = ry + r.get_height() / 2.0
cx = rx + r.get_width() / 2.0
cy = ry + r.get_height() / 2.0
self.ax.annotate(
f"{label}",
(cx, cy),
color="k",
backgroundcolor="w",
weight="bold",
fontsize=9,
ha="center",
va="center",
)
self.ax.set_xlabel(self.title)
self.done = True
def as_svg(self):
matplotlib.use("Agg") # Use pixel canvas backend instead of GUI backend
if not self.done:
self.compute()
svg = io.BytesIO()
plt.savefig(svg, format="svg")
return svg.getvalue().decode(encoding="UTF-8").strip()
def addnode(self, node, lower=[0, 0], upper=[1, 1], axis=0):
axis = axis % 2
hatch = self.draw_rectangle(lower, upper, node)
width = upper[axis] - lower[axis]
try:
for child in self.iter_method(node):
upper[axis] = lower[axis] + (
width * float(self.size_method(child))
) / self.size_method(node)
self.addnode(child, list(lower), list(upper), axis + 1)
lower[axis] = upper[axis]
except TypeError:
pass
def draw_rectangle(self, lower, upper, node):
h = None
if isinstance(node, int):
h = next(self.hatches_gen)
r = Rectangle(
lower,
upper[0] - lower[0],
upper[1] - lower[1],
edgecolor="k",
fill=False,
hatch=h,
)
self.ax.add_patch(r)
self.rectangles.append((node, r))
return h
from itertools import islice
import math
import random
from datamap import Treemap
from matplotlib import pylab
def random_label():
word_file = "/usr/share/dict/words"
words = [
w
for w in open(word_file).read().splitlines()
if not w.endswith("'s") and len(w) < 4 and len(w) > 1 and w.islower()
]
random.shuffle(words)
for w in words:
yield w
if __name__ == "__main__":
tree = ((5, (3, 5)), 4, (5, 2, (2, 3, (3, 2, 2)), (3, 3)), (3, 2))
labels = list(islice(random_label(), 15))
t = Treemap(f"tree {tree}", tree, labels)
t.compute()
pylab.show()
tree = (5, 4, 3, 2)
labels = [str(n + 1) for n in range(0, 5)]
t = Treemap(f"tree {tree}", tree, labels)
t.compute()
pylab.show()
"""
Show that the area ratios are correct:
"""
a = 500
b = 156
c = 301
total = a + b + c
tree = (a, b, c)
labels = [str(n) for n in tree]
t = Treemap(f"tree {tree}", tree, labels)
t.compute()
pylab.show()
get_area = lambda r: r.get_height() * r.get_width()
for (i, node) in enumerate(tree):
ratio = (node * 1.0) / total
rectangle_ratio = get_area(next(x for x in t.rectangles if x[0] == node)[1])
if not math.isclose(ratio, rectangle_ratio):
print(
"For node",
node,
"the ratio",
ratio,
"differs from rectangle ratio",
rectangle_ratio,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment