创建一个饼图


14

挑战很简单:

根据许多输入值创建一个饼图。

输入将是一个由正数,十进制或整数组成的列表,输出将是一个饼图,其中每个输入值都由单独的颜色表示,并且每个区域之外的百分比值。

规则:

  • 颜色必须在视觉上可以区分(确切的颜色是可选的)
  • 至少会有两个,最大为10个输入值
  • 圆的半径必须在[100 300]像素 范围内
    • 只要默认输出给出[100, 300]像素半径,矢量图形就可以
  • 百分比值应为整数
    • 没有严格的规则说明应将百分比值放在何处,但必须容易看出它属于哪个区域
    • 最接近的字符和圆的外边缘之间的距离必须在[5, 40]像素范围内
    • 字体是可选的
  • 该图可能有也可能没有黑线分隔每个区域
  • 不允许创建用于创建饼图的函数,例如MATLAB:pie,Python:matplotlib.pyplot.pie和Mathematica:PieChart
  • 正常的舍入规则(如果为(1.00, 0.5],则为up,如果为,则为down (0.5, 0.00)
  • 如果切片的百分比值小于0.5%,则输出0%。切片必须仍包含在图中。
  • 请提供检查用地(或指向口译员的链接)。仅显示带有10个输入值的图就足够了(避免很长的答案)

例子

请使用下面的示例值。您可以使用列表转换成合适的格式数字列表转换器,例如这27个字节一个jimmy23013

x = [0.3, 1.2] 

在此处输入图片说明

x = [3, 6, 2, 10]

在此处输入图片说明

x = [0.4387, 0.3816, 0.7655, 0.7952, 0.1869, 0.4898, 0.4456, 0.6463, 0.7094, 0.7547]

在此处输入图片说明


“圆的半径必须在[100 300]像素范围内。” 也可以使用矢量图形吗?
Martin Ender

@MartinBüttner,是的。可以,只要程序的输出看起来默认介于[100,300]之间即可。这是一个足够的答案吗?
Stewie Griffin

R将0.5舍入为0。这有问题吗?
Masclins '16

0.5如果这是默认值,则可以四舍五入为零。但0.50001必须四舍五入为1
Stewie新

Answers:


12

Mathematica,186 183 164字节

Graphics[{Hue@#,Disk[{0,0},{1,1},a=2Pi{##}],Black,Text[ToString@Round[100(#2-#)]<>"%",5Through@{Cos,Sin}@Mean@a/4]}&@@@Partition[Accumulate[#/Tr@#]~Prepend~0,2,1]]&

可以进一步打高尔夫球。当前生成一个Graphics对象。测试用例:




7

的JavaScript(ES6),311个 310 302 298字节

a=>{with(Math)document.write(`<svg height=300>`+a.map(n=>`<path fill=#${(p*4e3|0).toString(16)} d=M135,150L${c(o=100,v=0)}A${[o,o,0,(v=n/=s)+.5|0,0,c(o)]}Z /><text x=${(z=c(135,v/=2))[0]} y=${z[p+=n,1]}>${n*o+.5|0}%</text>`,c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150],p=s=0,a.map(n=>s+=n)).join``)}

在@Neil的帮助下保存了一个字节!

说明

将SVG写入当前页面的HTML。135 x 150以半径的中心点100px和文本与中心的半径为中心构建图表135px

var solution =

a=>{
  with(Math)
  document.write(       // write to HTML body
    `<svg height=300>`+ // create 300px x 300px SVG canvas (width defaults to 300px)
    a.map(n=>           // for each number
      
      // Get the hex colour by multiplying the current position by (roughly) 0xfff
      `<path fill=#${(p*4e3|0).toString(16)
      
      // Calculate the path of the pie slice
      } d=M135,150L${c(o=100,v=0)}A${[o,o,0,(v=n/=s)+.5|0,0,c(o)]
      
      // Text
      }Z /><text x=${(z=c(135,v/=2))[0]} y=${z[p+=n,1]}>${n*o+.5|0}%</text>`,
      
      // Returns [ x, y ] for a certain radius at position v around the pie
      c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150],
      p=s=0,             // p = current position around pie (0 - 1)
      a.map(n=>s+=n)     // s = sum of all numbers
    ).join``
    
    +`</svg>` // <- this is just here for the test, so multiple charts can be displayed
  )
}

// Test
;[
  [0.3, 1.2],
  [3, 6, 2, 10],
  [0.4387, 0.3816, 0.7655, 0.7952, 0.1869, 0.4898, 0.4456, 0.6463, 0.7094, 0.7547]
].map(c=>solution(c));


我认为您可以使用节省一些字节with(Math)c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150]
尼尔

嗯,你可能需要写with(Math)var solution = a=>
尼尔

嗯,实际上我可以使用with。我想我上次尝试时可能一直处于严格模式下
user81655 '16

@Neil在那里,谢谢。我很确定在这方面还可以做更多的高尔夫运动,因为我在写时有点着急。
user81655 '16

仅保存1个字节?我想这是一个开始……
Neil

6

Python + PIL,365 355

from math import*;from random import*
from PIL import Image,ImageDraw
L,a,r=256,0,0.8;l,p,c=L/2,L/6,(L,L,L);I=Image.new('RGB',(L,L),c);D=ImageDraw.Draw(I)
x=input()
for i in x:b=a+ceil(360.0*i/sum(x));D.pieslice((p,p,L-p,L-p),int(a),int(b),tuple(map(randrange,c)));t=(a+b)*0.00872;D.text((l+cos(t)*l*r,l+sin(t)*l*r),str(int((b-a)/3.6))+'%',0);a=b
I.show()

在此处输入图片说明

最大示例列表的结果:

在此处输入图片说明


在Python 2中,它不eval(raw_input())等同于Python 2 input()吗?

@cat是的!
节食者
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.