สร้างแผนภูมิวงกลม


14

ความท้าทายนั้นง่าย:

สร้างแผนภูมิวงกลมตามจำนวนค่าอินพุต

อินพุตจะเป็นรายการของตัวเลขบวกทศนิยมหรือจำนวนเต็มและเอาต์พุตจะเป็นแผนภูมิวงกลมซึ่งแต่ละค่าอินพุตจะแสดงด้วยสีแยกต่างหากและค่าเปอร์เซ็นต์นอกแต่ละพื้นที่

กฎ:

  • สีต้องมีความแตกต่างทางสายตา (สีที่แน่นอนเป็นตัวเลือก)
  • จะมีอย่างน้อยสองค่าสูงสุด 10 ค่า
  • รัศมีของวงกลมจะต้องอยู่ในช่วง[100 300]พิกเซล
    • กราฟิกแบบเวกเตอร์นั้นใช้ได้ตราบเท่าที่เอาต์พุตเริ่มต้นให้รัศมีของ[100, 300]พิกเซล
  • ค่าร้อยละจะต้องเป็นจำนวนเต็ม
    • ไม่มีกฎเกณฑ์ที่เข้มงวดที่จะบอกว่าจะต้องใส่ค่าเปอร์เซ็นต์ไว้อย่างไร แต่จะต้องเห็นได้ง่ายว่าเป็นพื้นที่ใด
    • ระยะห่างระหว่างตัวละครที่ใกล้เคียงที่สุดกับขอบด้านนอกของวงกลมจะต้องอยู่ในช่วง[5, 40]พิกเซล
    • แบบอักษรเป็นตัวเลือก
  • พล็อตอาจมีหรือไม่มีเส้นสีดำคั่นแต่ละภูมิภาค
  • ฟังก์ชันที่สร้างขึ้นสำหรับการสร้างแผนภูมิวงกลมเช่น MATLAB:, piePython: matplotlib.pyplot.pieและ Mathematica: PieChartไม่ได้รับอนุญาต
  • กฎการปัดเศษแบบปกติ (ขึ้นถ้า(1.00, 0.5]ลงถ้าเป็น(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

มันโอเคที่จะปัดเศษ0.5เป็นศูนย์ถ้ามันเป็นค่าเริ่มต้น แต่0.50001จะต้องปัดเศษเป็น 1
Stewie Griffin

คำตอบ:


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]ฉันคิดว่าคุณสามารถบันทึกไม่กี่ไบต์โดยใช้
Neil

อืมคุณอาจจะต้องเขียนwith(Math)var solution = a=>ฯลฯ
Neil

อืมฉันสามารถใช้งานwithได้จริง ฉันคิดว่าฉันอาจอยู่ในโหมดเข้มงวดเมื่อฉันลองใช้ครั้งสุดท้าย ...
user81655

@ Neil เข้าใจแล้วในนั้นขอบคุณ ฉันค่อนข้างมั่นใจว่ามีการตีกอล์ฟอีกเล็กน้อยที่สามารถทำได้ในเรื่องนี้เนื่องจากฉันกำลังรีบไปสักพักเมื่อฉันเขียนมัน
user81655

บันทึกเพียง 1 ไบต์ ฉันเดาว่ามันเป็นจุดเริ่มต้น ...
นีล

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 ใช่มันเป็น!
Dieter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.