โปรเจ็กต์ Matplotlib

หน้านี้มีรายละเอียดของโครงการเขียนเชิงเทคนิคที่ยอมรับใน Google Season of Docs

ข้อมูลสรุปของโปรเจ็กต์

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

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

แรงจูงใจ

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

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

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

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

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

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

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

ในการใช้ตัวอย่างของ linestyle อีกครั้ง สิ่งที่เราต้องการในเอกสาร LineCollection มีดังนี้

  1. ลิงก์ไปยังเอกสารฉบับเต็มสำหรับอินพุตที่อนุญาต (ทั้ง 2 อย่างที่พบใน 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 แบบเอกสาร (API-doc-explosion) ซึ่งการสแกนตัวเลือกที่เป็นไปได้มากมายสำหรับแต่ละพารามิเตอร์จะทำให้การสร้าง DOCT แต่ละรายการยุ่งยาก

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

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

การใช้งาน

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

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

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

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

ดูเอกสารเวอร์ชันที่เผยแพร่อยู่ได้ในวาทกรรมของเรา