โปรเจ็กต์ Matplotlib

หน้านี้มีรายละเอียดของโปรเจ็กต์การเขียนเชิงเทคนิคที่ได้รับการยอมรับสำหรับ Google Season of Docs

สรุปโปรเจ็กต์

องค์กรโอเพนซอร์ส
Matplotlib
นักเขียนเชิงเทคนิค
brunobeltran
ชื่อโปรเจ็กต์:
การปรับปรุงการค้นพบฟีเจอร์โดยการทำให้เอกสารประเภท "โดยนัย" เป็นมาตรฐาน
ระยะเวลาของโปรเจ็กต์
ดำเนินงานมาอย่างยาวนาน (5 เดือน)

คำอธิบายโปรเจ็กต์

แรงจูงใจ

ที่ผ่านมา API ของ matplotlib อาศัยสตริงเป็น Enum และ ""ประเภทโดยนัย"" เป็นอย่างมาก นอกจากการเลียนแบบ API ของ matlab แล้ว สตริงพารามิเตอร์เหล่านี้ยังช่วยให้ผู้ใช้ส่งค่าที่สื่อความหมายเป็นอาร์กิวเมนต์ไปยังฟังก์ชัน matplotlib ได้โดยไม่ต้องนำเข้าหรือใส่คำนำหน้าค่า enum จริงอย่างละเอียดเพื่อส่งตัวเลือกผังพื้นฐาน (เช่น plt.plot(x, y, linestyle='solid') พิมพ์ง่ายกว่าและไม่ซ้ำซ้อนกว่า plt.plot(x, y, linestyle=mpl.LineStyle.solid))

ประเภทโดยนัยของสตริงเป็นสตริงที่มีพัฒนาการเหล่านี้มีการพัฒนาฟีเจอร์ที่มีความซับซ้อนมากขึ้นตั้งแต่นั้นเป็นต้นมา ตัวอย่างเช่น ตอนนี้ linestyle อาจเป็นสตริงหรือทูเพลต 2 รายการของลําดับ และ MarkerStyle อาจเป็นสตริงหรือ matplotlib.path.Path แม้ว่าจะเป็นความจริงสำหรับประเภทโดยนัยหลายประเภท แต่ MarkerStyle เป็นเพียงประเภทเดียว (เท่าที่ฉันทราบ) ที่มีสถานะได้รับการอัปเกรดเป็นคลาส Python ที่เหมาะสม

เนื่องจากประเภทโดยนัยเหล่านี้ไม่ใช่คลาสในตัวเอง Matplotlib จึงต้องใช้โซลูชันของตัวเองในอดีตเพื่อรวมเอกสารประกอบและการตรวจสอบประเภทโดยนัยเหล่านี้ไว้ที่ส่วนกลาง (เช่น รูปแบบการหาค่าระหว่างของ docstring docstring.interpd.update และรูปแบบโปรแกรมตรวจสอบ cbook._check_in_list ตามลำดับ) แทนที่จะใช้ชุดเครื่องมือมาตรฐานที่คลาส Python มีให้ (เช่น docstring และรูปแบบ validate-at-__init__ ตามลำดับ)

แม้ว่าโซลูชันเหล่านี้จะทำงานได้ดีสำหรับเรา แต่การไม่มีตำแหน่งที่ชัดเจนในการอธิบายประเภทที่นัยของแต่ละประเภททำให้เอกสารประกอบมักจะหายาก ตารางค่าที่อนุญาตขนาดใหญ่ซ้ำกันตลอดทั้งเอกสารประกอบ และบ่อยครั้งที่เอกสารประกอบไม่มีข้อความที่ชัดเจนเกี่ยวกับขอบเขตของประเภทที่นัย ยกตัวอย่างเช่น เอกสาร plt.plot ในส่วน ""หมายเหตุ"" คำอธิบายวิธีการจัดรูปแบบสตริงรูปแบบที่คล้ายกับ matlab กล่าวถึงตัวเลือก linestyle, color และ markers การส่งค่า 3 รายการนี้ทำได้หลายวิธีกว่าที่บอกไว้ แต่สําหรับผู้ใช้จํานวนมาก นี่เป็นแหล่งข้อมูลเดียวที่เข้าใจเกี่ยวกับค่าที่ใช้ได้สําหรับตัวเลือกเหล่านั้นจนกว่าจะพบบทแนะนําที่เกี่ยวข้อง มีตารางแอตทริบิวต์ Line2D อยู่ด้วยเพื่อแสดงตัวเลือกต่างๆ ที่ผู้อ่านมีในการควบคุมพล็อต อย่างไรก็ตาม แม้ว่ารายการ linestyle จะลิงก์กับ Line2D.set_linestyle ได้ดี (ต้องคลิก 2 ครั้ง) เมื่อมีการอธิบายอินพุตที่เป็นไปได้ แต่รายการ color และ markers ไม่ได้ทำเช่นนั้น color เพียงลิงก์ไปยัง Line2D.set_color ซึ่งไม่ได้ให้ข้อมูลว่าอินพุตประเภทใดบ้างที่อนุญาต

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

เป้าหมายสุดท้าย

ตามหลักการแล้ว การกล่าวถึงประเภทโดยนัยควรลิงก์ไปยังหน้าเว็บเดียวที่อธิบายค่าที่เป็นไปได้ทั้งหมดที่ประเภทนั้นๆ สามารถรับได้ โดยเรียงลำดับจากเรียบง่ายที่สุด และพบบ่อยที่สุด ไปจนถึงขั้นสูงหรือลึกลับที่สุด แทนที่จะใช้พื้นที่ภาพที่มีค่าในเอกสารประกอบ API ระดับบนสุดเพื่อแสดงรายการประเภทอินพุตที่เป็นไปได้ทั้งหมดสำหรับพารามิเตอร์หนึ่งๆ เราสามารถใช้พื้นที่เดียวกันนั้นเพื่ออธิบายสิ่งที่เป็นนามธรรมของการพล็อตที่พารามิเตอร์มีไว้เพื่อควบคุม

หากใช้ตัวอย่าง linestyle อีกครั้ง สิ่งที่เราต้องการในเอกสาร LineCollection ก็คือ

  1. ลิงก์ไปยังเอกสารที่สมบูรณ์สำหรับอินพุตที่อนุญาต (ชุดค่าผสมของข้อมูลที่อยู่ใน Line2D.set_linestyle และบทแนะนำสไตล์บรรทัด)
  2. คำอธิบายแบบคำง่ายๆ ว่าพารามิเตอร์นี้มีหน้าที่อะไร ผู้ใช้ matplotlib ที่มีประสบการณ์จะทราบจากชื่อพารามิเตอร์ แต่ผู้ใช้ใหม่อาจไม่เข้าใจ

ลักษณะที่ข้อมูลนี้จะปรากฏในเอกสาร LineCollection จริงจะเหมือนกับแค่ python """""" linestyles: `LineStyle` or list thereof, default: :rc:`lines.linestyle` ('-') A description of whether the stroke used to draw each line in the collection is dashed, dotted or solid, or some combination thereof. """""" ที่ Sphinx จะแก้ไขการอ้างอิงประเภท LineStyle เพื่อชี้ไปที่ชุดเอกสารประกอบที่สมบูรณ์ เชื่อถือได้ และชุดเดียวเกี่ยวกับวิธีที่ Matplotlib จัดการรูปแบบเส้น

ประโยชน์

ฟีเจอร์ที่มีประสิทธิภาพบางอย่างของแนวทางนี้ ได้แก่

  1. แสดงความสามารถของฟังก์ชันแต่ละรายการอย่างชัดเจนในรูปแบบข้อความธรรมดา (ไม่ต้องคลิกใดๆ)
  2. ทำให้ตัวเลือกเริ่มต้นปรากฏขึ้น (ไม่มีการคลิก) การได้เห็นตัวเลือกเริ่มต้น ก็มักเพียงพอต่อความจำของผู้ใช้ที่กลับมา
  3. เขียนคำอธิบายตัวเลือก "ที่ใช้บ่อยที่สุด" และ "ง่ายที่สุด" สำหรับพารามิเตอร์ที่พร้อมใช้งานเมื่อเรียกดู (ด้วยการคลิกเพียงครั้งเดียว) ให้สมบูรณ์
  4. ค้นพบฟีเจอร์และวิธีการป้อนข้อมูลอันทรงประสิทธิภาพมากขึ้นได้ง่ายๆ เพียง "เลื่อนลง" เพื่อดูตัวเลือกขั้นสูงเพิ่มเติม (โดยยังคงคลิกเพียงครั้งเดียว)
  5. ระบุกลยุทธ์แบบรวมศูนย์สำหรับการลิงก์เอกสาร ""API"" ระดับบนสุดกับ ""บทแนะนํา"" ที่เกี่ยวข้อง
  6. หลีกเลี่ยงการแพร่กระจายของเอกสาร API เนื่องจากการสแกนตัวเลือกที่เป็นไปได้มากมายสำหรับแต่ละพารามิเตอร์จะทำให้เอกสารแต่ละสตริงไม่เป็นระเบียบ

ประโยชน์อื่นๆ ของแนวทางนี้เมื่อเทียบกับเอกสารปัจจุบันมีดังนี้

  1. เอกสารมีแนวโน้มที่จะล้าสมัยน้อยลงเนื่องจากการรวมศูนย์
  2. การทำให้ ""มาตรฐานโดยนัย"" ของ matplotlib จำนวนมากเป็นมาตรฐานเดียวกัน (เช่น ความแตกต่างระหว่าง ""bounds"" กับ ""extents"") ซึ่งปัจจุบันต้องเรียนรู้ด้วยการอ่านโค้ด
  3. กระบวนการนี้จะไฮไลต์ปัญหาเกี่ยวกับความสอดคล้องของ API ในลักษณะที่ติดตามได้ง่ายขึ้นผ่านเครื่องมือติดตามปัญหาของ GitHub ซึ่งจะช่วยในกระบวนการปรับปรุง API
  4. เวลาที่ใช้ในการสร้างเอกสารเร็วขึ้น เนื่องจากจำนวนข้อความที่ต้องแยกวิเคราะห์ลดลงอย่างมาก

การใช้งาน

การปรับปรุงที่อธิบายข้างต้นจะต้องอาศัยความพยายามที่สำคัญ 2 อย่าง ซึ่งนักเขียนด้านเทคนิคที่เชี่ยวชาญจะมีประโยชน์อย่างยิ่ง วิธีแรกคือสร้างหน้า "บทแนะนำ" แบบรวมศูนย์ 1 หน้าต่อประเภทแบบนัย โดยจะต้องทำงานร่วมกับทีมนักพัฒนาซอฟต์แวร์หลัก เพื่อระบุรายการประเภทโดยนัยที่แน่ชัด ซึ่งเอกสารประกอบจะมีประโยชน์ต่อผู้ใช้ (โดยปกติแล้วจะมีฟีเจอร์ที่ซ่อนอยู่ในไลบรารีของเราซึ่งมีประสิทธิภาพ) ซึ่งปัจจุบันมีเอกสารประกอบอยู่เฉพาะในบทแนะนำที่เข้าใจยาก) สำหรับประเภทที่ไม่ชัดแต่ละประเภท เราจะรวบรวมบทแนะนำ เอกสาร API และหน้าตัวอย่างที่เกี่ยวข้องต่างๆ เข้าด้วยกันเป็นแหล่งข้อมูลที่น่าเชื่อถือแหล่งเดียวซึ่งลิงก์ไปยังทุกที่ที่มีการอ้างอิงประเภทนั้นๆ ได้

เมื่อเอกสารประกอบแบบรวมศูนย์สําหรับประเภทแบบนัยหนึ่งๆ เสร็จสมบูรณ์แล้ว งานสำคัญลำดับที่ 2 จะเริ่มขึ้น ซึ่งก็คือการแทนที่เอกสารประกอบ API ที่มีอยู่ด้วยลิงก์ไปยังเอกสารประกอบใหม่ โดยมีจุดมุ่งหมายเพื่อทําให้ประสบการณ์การใช้งานเอกสารประกอบใหม่นี้ง่ายที่สุดเท่าที่จะเป็นไปได้ ทั้งสําหรับผู้ที่ใช้ยูทิลิตี help() ในตัวของ Python และผู้ที่เรียกดูเอกสารประกอบทางออนไลน์

แม้ว่ารูปแบบที่แน่นอนของเอกสารประกอบที่เสนอที่นี่อาจมีการเปลี่ยนแปลงไปเมื่อโปรเจ็กต์นี้พัฒนาไป แต่เราได้ทํางานร่วมกับทีมหลักของ Matplotlib ในระหว่าง ""การโทรหานักพัฒนาซอฟต์แวร์"" ประจำสัปดาห์เพื่อหาข้อสรุปว่ากลยุทธ์ที่เสนอที่นี่เป็นแนวทางที่สะดวก มีประโยชน์ และจัดการได้ทางเทคนิคมากที่สุดในการเริ่มจัดทำเอกสารประกอบเกี่ยวกับ ""ประเภทโดยนัย"" เหล่านี้ (หมายเหตุเกี่ยวกับการโทรเหล่านี้มีใน hackmd) ฉันจะใช้โครงสร้างพื้นฐาน ""บทแนะนำ" ที่มีอยู่สำหรับขั้นตอนเริ่มต้นในการสร้างเอกสารประกอบแบบรวมศูนย์สำหรับแต่ละประเภทโดยปริยาย ซึ่งช่วยให้ฉันอ้างอิงหน้าเหล่านี้ได้ง่ายๆ ดังนี้ โดยไม่ต้องสร้างคลาสสาธารณะใหม่ (เช่น โดยใช้เอกสาร LineCollection เป็นตัวอย่างอีกครั้ง)

""""""
linestyles: LineStyle or list thereof, default: :rc:`lines.linestyle` ('-')
    A description of whether the stroke used to draw each line in the collection
    is dashed, dotted or solid, or some combination thereof. For a full
    description of possible LineStyle's, see :doc:`tutorials/types/linestyle`.
""""""

นับจากนี้ไป เราจะเปลี่ยนวิธีสะกดการอ้างอิงเหล่านี้ได้อย่างง่ายดายเมื่อทีมนักพัฒนาซอฟต์แวร์หลักเห็นด้วยกับกลยุทธ์ระยะยาวที่ดีที่สุดในการรวมเอกสารประกอบ ""ประเภท"" ใหม่ของเราไว้ในคลาส Python ที่ถูกต้อง เช่น ตามที่ฉันเสนอไว้ในข้อเสนอการปรับปรุง Matplotlib 30

สุดท้ายนี้ รายการเบื้องต้นของประเภทโดยนัยที่เราขอแนะนำให้บันทึกไว้ในช่วง Google Season of Docs มีดังนี้

  1. capstyle
  2. joinstyle
  3. bounds
  4. extents
  5. linestyle
  6. colors/lists of colors
  7. colornorm/colormap
  8. tick formatters

ดูเอกสารฉบับปรับปรุงล่าสุดได้ใน Discourse