تغییر مقیاس در دستگاه مختصات

plot

#1

تصمیم گرفتم به جای استفاده از کتابخونۀ matplotlib، که کتابخونۀ اصلی پایتون برای نمایش داده ها محسوب میشه، با استفاده از tkinter (که بیشتر برای ساخت رابط کاربری گرافیکی به کار میره) یه دستگاه مختصات ساده برای نمایش داده ها بسازم. مشکلاتی که باهاش برخورد کردم بیشتر به ریاضیات مربوط میشه تا به زبان برنامه نویسی خاصی. مثلاً:

  • توی یه صفحه که عرض و طولش هر دو 500 پیکسل هستن، چطور میشه همزمان اعداد خیلی یزرگ (مثلاً 100 رقمی) و اعداد خیلی کوچیک (بین 0 و 1) رو نمایش داد؟ و نموداری که رسم میشه باید داخل محدودۀ صفحه بمونه و فراتر از اون نره.

  • مبدا مختصاتمون رو اگر مجبور شدیم تغییر بدیم، مثلا وقتی نود درصد داده ها منفی هستن، کجای صفحه بزاریم؟ چون در اینصورت گوشۀ پایین و چپ صفحه، و وسط صفحه دیگه جای مناسبی برای قرارگرفتن مبدا محسوب نمیشن.

  • اگر تعداد داده ها بیشتر از 500 تا باشه، با توجه به اینکه ابعاد صفحه 500 پیکسل هست، و با توجه به اینکه مینیمم واحد تغییراتی که داریم 1 پیکسله، چطور همه رو نمایش بدیم؟ اگر مجبور باشیم یه تعدادی رو حذف کنیم و نمایش ندیم، کدوم ها رو انتخاب کنیم؟

راهنمایی کنید لطفاً. کتاب تخصصی، ریاضی یا برنامه نویسی هم اگه در ارتباط با این موضوع میشناسید معرفی کنید. برای هر زبان برنامه نویسی ای باشه فرق نداره.


#2

منظور تغییر مقیاس به چه صورته؟ اصلا چرا باید مقیاس تغییر کنه؟
در ضمن لطفا همیشه کمی در مورد موضوع توضیح بدین، مثلا این که شما در مورد کتابخونه های پایتون سخن می گید :hugs:


#3

یه نسبت تناسب سادست! نیازی به کتاب و مقاله و اینطور چیزا نداره!

#python3

def resizer(
        xy,
        original_size = (1500, 1200),
        required_size = (500, 500),
        ):
    # douple slash to get integer
    x = xy[0] * required_size[0] // original_size[0]
    y = xy[1] * required_size[1] // original_size[1]
    return (x, y)

original_pixel = (1111, 123)
result = resizer(original_pixel)
print(result)

#4

چون کمترین میزان تغییرات یک پیکسل هست. وقتی قرار باشه چنتا نقطه که مختصاتشون حداکثر دو رقمیه و چنتا نقطه دیگه که مختصاتشون مثلاً هفت رقمیه، همزمان تو یه صفحه ای قرار بگیرن که کلاً 500 پیکسله، خوب نمیشه از مختصات خام استفاده کرد و باید تغییرش داد…
چشم، توضیحات اضافی رو به متن اضاف میکنم :slightly_smiling_face:


#6

فک کنم درسته :grin:
به جای مختصات original_size باید ماکسیمم و مینیمم x ها و y ها رو بزارم؟


#7

بله.
اعداد original_size مربوط به سایز قبلی هستن و required_size ابعادی که میخوایم داشته باشیم.


#8

اعداد منفی چی میشن؟ مثلاً بخوام یه نقطه که x اِش 50 هزاره و یه نقطه دیگه که x اِش منفی 50 هزاره رو تو صفحه 500 در 500 نمایش بدم، یکیش میشه 500 اون یکی میشه منفی 500.
اینجا original_size مختص x اِش میشه 50 هزار دیگه؟ اگه هیچ x دیگه ای تو داده هام نباشه که بیشتر 50 هزار باشه.


#9

منظورم این بود که همینا رو اول کمی توضیح بدی و کلا موضوع بحث روشن بشه، که دیگرانی که علاقه مند هستند از جمله خود من یه چیزی یاد بگیرند.
ممنون :smiling_face_with_three_hearts:


#10

بله باید محدوده مختصات مشخص باشه


#11

منفی که نداریم!
اگه میخوایم منفی نشون بدیم باید صفر رو به سمت راست منتقل کنیم.
یه راه ساده برای این کار هست.

اگه کوچیکترین عددمون مثلا -120 هست، همه‌ی اعداد رو +120 کنیم (که کوچیکترین عددمون بشه صفر). بعد تابع بالا رو روشون اجرا کنیم.
راههای پیچیده تری هم هست که اصلا نیاز نیست بهشون فکر کنیم چون مسیر ما اونطرفی نیست.


پیاده سازی این سیستم به این سادگی که گفتم نیست. اون تابعی که بالاتر نوشتم هم باید یه کم اصلاح بشه.
کل سیستم باید به این صورت باشه که ما اول همه‌ی «زوج مرتب»‌های ارجینال رو توی یه لیست بریزیم. بعد بدیمش به یه تابع که یه پردازش اولیه روش انجام بده (مثلا کوچیکترین و بزرگترین مقدارها رو پیدا کنه و اگه منفی داریم، کل اعداد رو به سمت مثبتها shift کنه)
بعد با همون قضیه‌ی نسبت تناسب بیایم به اندازه‌ای که میخوایم درش بیاریم و بعد نمودار رو رسم کنیم.


اگه Functional Programming کار میکنید، پیشنهاد میدم حتما این مسیر رو به توابع کوچیک تقسیم کنید. تابع بزرگی که چندتا کار انجام بده زیاد اصولی نیست. بهتره توابع کوچیک و ساده (منظورم simple هست) باشن که ویرایش و رفع ایرادشون راحتتر باشه و وقتی به کد نگاه میکنیم بفهمیم الآن داره چیکار میکنه و وضعیت دیتاها به چه صورت هست.
نکته‌ی دیگه که مهم هست اینه که وقتی توابع کوچیک باشن و کارشون مشخص باشه، میشه چندبار ازشون استفاده کرد (reusable code -aka- don’t repeat yourself) و اگه جای دیگه‌ای به یه قسمت از این کد نیاز داشتیم لازم نیست کپی کنیم یا یه قسمت از کد رو مجددا بنویسیم.

اگر هم Object Oriented کار میکنید، تنها پیشنهادی که میتونم بکنم اینه که بیاید سراغ FP. والسلام :upside_down_face: