globals [ page-color ink-color margin scale ink-patches piechart barchart mapchart line-width ] breed [ charts chart ] charts-own [ !top ;; top(max-y) of the chart region !bottom ;; bottom (min-y) of the chart !left ;; left (min-x) of the chart !right ;; right (max-x) of the chart .top ;; top of the CANVAS .bottom ;; and so on .left .right .centerx .centery !width .width .height region ;; all the patches in the subchart border ;; the patches that surround the canvas canvas ;; the patches inside the border axis ;; part of the graph ink that never changes, ;; eg the circle around the pie, the lines under the bars field ;; part of the graph ink that changes rad ] patches-own [ a ] to startup reset repeat 20 [ go ] end to reset initialize end to initialize ca set page-color white set ink-color black set margin int ( .5 + world-height * .05) set scale .8 set line-width floor (.5 + world-height * .025) set piechart new-chart 3 1 "pie" set barchart new-chart 3 2 "bar" set mapchart new-chart 3 3 "map" step0 end to step0 ask patches [ set pcolor page-color ] ask charts [ draw-border draw-axis ] end to clear-region ask region [ set pcolor page-color ] end to draw-border ask border [ set pcolor ink-color ] end to draw-axis ask axis [ set pcolor ink-color ] end to clear-canvas ask canvas [ set pcolor page-color ] end to-report new-chart [ #charts #chart #type] ;; charts is number of charts overall ;; chart is the number of this chart let me nobody output-print (word "creating chart " #chart ) create-charts 1 [ set me self set heading 0 set color black set size 0 hide-turtle let chart-width floor (world-width / #charts) set !top max-pycor set !bottom min-pycor set !left chart-width * (#chart - 1) set !right chart-width * #chart set .top !top - (margin + line-width) set .bottom !bottom + (margin + line-width) set .left !left + (margin + line-width) set .right !right - (margin + line-width) set .centerx .5 * (.left + .right) set .centery .5 * (.top + .bottom) set !width ( !right - !left ) set .width ( .right - .left ) set .height ( .top - .bottom ) setxy .centerx .centery d "---creating region" let !left! !left let !right! !right let !top! !top let !bottom! !bottom let .left. .left let .right. .right let .top. .top let .bottom. .bottom set region patches with [ !left! <= pxcor and pxcor <= !right! and !bottom! <= pycor and pycor <= !top! ] paint region 135 d "---creating canvas" set canvas region with [ .left. <= pxcor and pxcor <= .right. and .bottom. <= pycor and pycor <= .top. ] paint canvas 125 d "---creating border" set border region with [ ;; left and right side ( !bottom! + margin < pycor and pycor < !top! - margin and ( (!left! + margin) < pxcor and pxcor < .left. or .right. < pxcor and pxcor < (!right! - margin) ) ) or ;; top and bottom side ( !left! + margin < pxcor and pxcor < !right! - margin and ( !bottom! + margin < pycor and pycor < .bottom. or .top. < pycor and pycor < (!top! - margin) ) ) ] paint border 115 d "---creating axis" set axis no-patches if #type = "pie" [ let $cx xcor let $cy ycor set rad (.right - .left) * scale * .5 let $canvas canvas let $rad rad let $rad1 rad - (line-width / 2) let $rad2 rad + (line-width / 2) let $rad3 rad - line-width set axis canvas with [ in-ring $rad1 $rad2 ] set field canvas with [ distance myself <= $rad3 ] ] if #type = "bar" [ let margin2 margin + margin set axis (patch-set canvas with [ .left. + margin2 < pxcor and pxcor < .right. - margin2 and .bottom. + margin2 < pycor and pycor < .bottom. + margin2 + line-width ] canvas with [ .bottom. + margin2 < pycor and pycor < .top. - margin2 and .left. + margin2 < pxcor and pxcor < .left. + margin2 + line-width ] ) set field canvas with [ .left. + margin2 + line-width < pxcor and pxcor < .right. - margin2 - line-width and .bottom. + margin2 + line-width < pycor and pycor < .top. - margin2 - line-width ] ] paint axis 95 ] report me end to-report quick-distance [ agent ] let x pxcor - [ pxcor ] of agent let y pycor - [ pycor ] of agent report ( x * x + y * y ) end to-report safe-patch-towards-turtle [ a-turtle ] ifelse pxcor != [ xcor ] of a-turtle or pycor != [ ycor ] of a-turtle [ report towards a-turtle ] [ report 0 ] end to go let allpix count patches let inked count patches with [ pcolor = ink-color ] let blank allpix - inked let inkratio inked / allpix ;; update PIE CHART of PROPORTION OF PIXELS that are WHITE ask piechart [ let inkangle 360 * inkratio ask field [ ifelse safe-patch-towards-turtle myself < inkangle [ set pcolor ink-color ] [ set pcolor page-color ] ] ] ;; update BAR CHART of RELATIVE AMOUT OF WHITE PIXELS ask barchart [ let $base .bottom + 4 let max-ratio 0 let $bar-shift ( .width / 16 ) let $bar-width $bar-shift * 2 + 1 let $bar-hscale 2 ask field [ set pcolor page-color ] let field.left min [ pxcor ] of field let field.right max [ pxcor ] of field let field.span field.right - field.left let bars count charts let bar.width field.span / bars let bar.top max [ pycor ] of field let bar.bottom min [ pycor ] of field + line-width let bar.height bar.top - bar.bottom let ink-ratios map [ (count [ region with [ pcolor = ink-color ] ] of ? ) / (count [ region ] of ? ) ](sort charts) let max-ink max ink-ratios let bar.scale bar.height / max-ink (foreach (sort charts) (n-values bars [ 1 + ? ]) (ink-ratios) [ let $chart ?1 let $index ?2 let $ink-ratio ?3 let bar.left field.left + bar.width * ($index - 1) + line-width * 2 let bar.right bar.left + bar.width - line-width * 2 let bar.adj.height bar.scale * $ink-ratio ask field with [ bar.left <= pxcor and pxcor <= bar.right and pycor < bar.bottom + bar.adj.height and pycor > bar.bottom ] [ set pcolor ink-color ] ]) ] ;; update GRAPH of PIXELS in IMAGE that are ink color ask patches [ set a 0 ] let .scale [((.width ) / !width) ] of mapchart ;; map all the patches into the field ask patches [ if pcolor = ink-color [ let mapx ([.left] of mapchart + .scale * pxcor / 3) let mapy ([.centery - .centery / 5 ] of mapchart + .scale * pycor / 3) ask patch mapx mapy [ set a a + 1 ] ] ] ask mapchart [ ask canvas [ ifelse a > 0 [ set pcolor ink-color ] [ set pcolor page-color ] ] ] tick end to d [ string ] output-print string end to paint [ #patches #pcolor ] ;; used during debugging ;ask #patches [ set pcolor #pcolor ] ;display end to-report in-ring [ d1 d2 ] let dd distance myself report (d1 <= dd and dd <= d2) end @#$#@#$#@ GRAPHICS-WINDOW 140 10 751 242 -1 -1 1.0 1 10 1 1 1 0 0 0 1 0 600 0 200 1 1 1 ticks CC-WINDOW 5 306 760 401 Command Center 0 BUTTON 10 10 95 43 reset reset repeat 10 [ go ] NIL 1 T OBSERVER NIL NIL NIL NIL TEXTBOX 15 60 120 235 Press reset to create the self-descriptive chart. It will take a few moments to stabilize. 11 0.0 1 TEXTBOX 160 250 310 292 Proportion of white pixels to black pixels in the entire diagram 11 0.0 1 TEXTBOX 360 250 510 278 Relative amount of black pixels in each chart 11 0.0 1 TEXTBOX 560 250 710 278 Map of the location of black pixels in the diagram 11 0.0 1 @#$#@#$#@ WHAT IS IT? ----------- Inspired by this XKCD cartoon by Randall Munroe: http://xkcd.com/688/ This is a chart that describes itself. This is a chart that shows information about the number of white pixels in this chart. The pie chart shows the proportion of white pixels to black pixels. The bar chart shows the relative quantity of white pixels in the three sub-charts. The xy chart shows the location of pixels in this chart that are white COPYRIGHT --------- This model is free to use with attribution for any legal non-commercial purpose. @#$#@#$#@ default true 0 Polygon -7500403 true true 150 5 40 250 150 205 260 250 @#$#@#$#@ NetLogo 4.0.4 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ default 0.0 -0.2 0 0.0 1.0 0.0 1 1.0 0.0 0.2 0 0.0 1.0 link direction true 0 Line -7500403 true 150 150 90 180 Line -7500403 true 150 150 210 180 @#$#@#$#@