خوارزمية لطيفة الرسم البياني تسميات الوقت/التاريخ محور ؟

StackOverflow https://stackoverflow.com/questions/1419194

  •  07-07-2019
  •  | 
  •  

سؤال

أنا أبحث عن "أرقام" خوارزمية لتحديد العلامات على قيمة تاريخ/وقت المحور.أنا على دراية بول Heckbert الجميل الأرقام الخوارزمية.

لدي المؤامرة التي تعرض الوقت/التاريخ على المحور X و يمكن للمستخدم تكبير والنظر في إطار زمني أصغر.أنا أبحث عن خوارزمية أن يختار لطيفة مواعيد عرض على القراد.

على سبيل المثال:

  • تبحث في يوم أو نحو ذلك:1/1 12:00, 1/1 4:00, 1/1 8:00...
  • تبحث في الأسبوع:1/1, 1/2, 1/3...
  • تبحث في الشهر:1/09, 2/09, 3/09...

لطيفة التسمية القراد لا تحتاج إلى تتوافق مع أول مرئية النقطة ، ولكن على مقربة منه.

هو أي شخص على دراية مع هذه الخوارزمية ؟

هل كانت مفيدة؟

المحلول

إن 'لطيفة الأرقام المقال الذي يرتبط ذكر أن

اجمل الأرقام العشرية هي 1 و 2 و 5 و كل قوة من 10 أضعاف هذه الأرقام

لذلك أعتقد أن على القيام بشيء مماثل مع التاريخ/الوقت عليك أن تبدأ من خلال وبالمثل كسر القطع المكونة.حتى تأخذ لطيفة العوامل من كل نوع من الفاصل الزمني:

  • إذا كنت تظهر ثوان أو دقائق الاستخدام 1, 2, 3, 5, 10, 15, 30 (أنا تخطي 6, 12, 15, 20 لأنهم لا "يشعر" الحق).
  • إذا كنت تبين ساعات استخدام 1, 2, 3, 4, 6, 8, 12
  • لأيام استخدام 1 ، 2 ، 7
  • لأسابيع استخدام 1 ، 2 ، 4 (13 و 26 تناسب نموذج ولكن يبدو لي غريبا)
  • أشهر استخدام 1, 2, 3, 4, 6
  • لسنوات استخدام 1 ، 2 ، 5 و السلطة من مضاعفات 10

الآن من الواضح أن هذا يبدأ لكسر كما يمكنك الحصول على إلى كميات أكبر.بالتأكيد أنت لا تريد أن تظهر 5 أسابيع يستحق دقائق ، حتى في "جميلة" فترات من 30 دقيقة أو ما شابه.من ناحية أخرى, عندما يكون لديك فقط 48 ساعة قيمتها ، أنت لا تريد أن تظهر 1 يوما.خدعة كما ذكرتم هو إيجاد الكريم انتقال نقطة.

فقط على حدس, وأود أن أقول معقول نقطة التقاطع سيكون حوالي ضعفي الفترة المقبلة.التي من شأنها أن تعطيك التالية (min و max عدد فترات تبين بعد ذلك)

  • استخدام ثوان إذا كان لديك أقل من 2 دقائق قيمتها (1-120)
  • استخدام دقائق إذا كان لديك أقل من 2 ساعة بقيمة (2-120)
  • استخدام ساعات إذا كان لديك أقل من 2 أيام بقيمة (2-48)
  • استخدام أيام إذا كان لديك أقل من 2 أسابيع قيمتها (2-14)
  • استخدام أسابيع إذا كان لديك أقل من 2 أشهر بقيمة (2-8/9)
  • استخدام أشهر إذا كان لديك أقل من 2 سنوات بقيمة (2-24)
  • وإلا استخدم سنوات (على الرغم من أنك يمكن أن يستمر مع عقود و قرون إلخ إذا النطاقات الخاصة بك يمكن أن يكون هذا الوقت الطويل)

للأسف لدينا تتعارض فترات زمنية يعني أن كنت في نهاية المطاف مع بعض الحالات التي يمكن أن يكون لها أكثر من 1 مائة فترات في حين أن آخرين لديهم على الأكثر 8 أو 9.لذلك عليك أن ترغب في اختيار حجم فترات هذا مما لا يكون أكثر من 10-15 فترات في معظم (أو أقل من 5 في هذا الشأن).أيضا, يمكنك كسر من تعريف دقيق 2 مرات أكبر الفاصل إذا كنت تعتقد أن من السهل أن تتبع.فعلى سبيل المثال ، يمكن استخدام ساعة إلى 3 أيام (72 ساعة) أسابيع تصل إلى 4 أشهر.قليلا من التجربة والخطأ قد يكون ضروريا.

لذلك يذهب إلى أكثر من اختيار نوع الفاصل الزمني على أساس حجم النطاق الخاص بك ، ثم اختر فاصل الحجم من خلال اختيار واحدة من "لطيفة" الأرقام التي سوف أترك لكم مع بين 5 و 15 علامة من علامات.أو إذا كنت تعرف و/أو يمكن السيطرة الفعلية عدد البكسل بين علامات التجزئة يمكن وضع الحدود العليا والدنيا على كم بكسل مقبولة بين القراد (إذا كانت متباعدة متباعدة جدا في الرسم البياني قد يكون من الصعب قراءة ، ولكن إذا كان هناك الكثير من القراد على الرسم البياني سوف يكون تشوش التسميات الخاصة بك قد تتداخل).

نصائح أخرى

لا يوجد حتى الآن إجابة على هذا السؤال ...سأطرح فكرتي الأولى في ذلك الوقت!أفترض أن لديك نطاق المحور المرئي.

ربما هذا هو ما سأفعله.

الزائفة الخام:

// quantify range
rangeLength = endOfVisiblePart - startOfVisiblePart;

// qualify range resolution
if (range < "1.5 day") {
    resolution = "day";  // it can be a number, e.g.: ..., 3 for day, 4 for week, ...
} else if (range < "9 days") {
    resolution = "week";
} else if (range < "35 days") {
    resolution = "month";
} // you can expand this in both ways to get from nanoseconds to geological eras if you wish

بعد ذلك، ينبغي (اعتمادًا على ما يمكنك الوصول إليه بسهولة) أن يكون من السهل جدًا تحديد القيمة لكل علامة تسمية لطيفة.اعتمادًا على "الدقة"، يمكنك تنسيقها بشكل مختلف.على سبيل المثال:MM/DD لـ "الأسبوع"، MM:SS لـ "دقيقة"، وما إلى ذلك، تمامًا كما قلت.

القي نظرة على

http://tools.netsa.cert.org/netsa-python/doc/index.html

يحتوي على ملف Nice.py ( python/netsa/data/nice.py ) والذي أعتقد أنه قائم بذاته ويجب أن يعمل بشكل جيد.

أقترح عليك الحصول على الكود المصدري لـ gnuplot أو RRDTool (أو حتى Flot) وفحص كيفية تعاملهم مع هذه المشكلة.من المحتمل أن تكون الحالة العامة عبارة عن تسميات N مطبقة بناءً على عرض قطعة الأرض الخاصة بك، والتي يتم "التقاطها" نوعًا ما إلى أقرب رقم "لطيف".

في كل مرة كتبت فيها مثل هذه الخوارزمية (مرات عديدة جدًا)، استخدمت جدول "التفضيلات"...أي:استنادًا إلى النطاق الزمني في المخطط، قرر ما إذا كنت سأستخدم الأسابيع والأيام والساعات والدقائق وما إلى ذلك كنقطة المحور الرئيسية.عادةً ما أقوم بتضمين بعض التنسيقات المفضلة، حيث نادرًا ما أرغب في رؤية تاريخ كل دقيقة أرسمها على الرسم البياني.

سأكون سعيدًا ولكن مندهشًا عندما أجد شخصًا يستخدم صيغة (مثلما يفعل هيكبرت) للعثور على كلمة "لطيف"، لأن التباين في الوحدات الزمنية بين الدقائق والساعات والأيام والأسابيع ليس خطيًا.

[تحرير - لقد قمت بتوسيع هذا أكثر قليلاً في http://www.acooke.org/cute/AutoScalin0.html ]

يبدو أن الامتداد الساذج لخوارزمية "الأرقام اللطيفة" يعمل مع الأساسين 12 و60، مما يعطي فترات زمنية جيدة للساعات والدقائق.هذا هو الكود الذي قمت باختراقه معًا للتو:

LIM10 = (10, [(1.5, 1), (3, 2), (7, 5)], [1, 2, 5])
LIM12 = (12, [(1.5, 1), (3, 2), (8, 6)], [1, 2, 6])
LIM60 = (60, [(1.5, 1), (20, 15), (40, 30)], [1, 15, 40])


def heckbert_d(lo, hi, ntick=5, limits=None):
    '''
    Heckbert's "nice numbers" algorithm for graph ranges, from "Graphics Gems".
    '''
    if limits is None:
        limits = LIM10
    (base, rfs, fs) = limits
    def nicenum(x, round):
        step = base ** floor(log(x)/log(base))
        f = float(x) / step
        nf = base
        if round:
            for (a, b) in rfs:
                if f < a:
                    nf = b
                    break
        else:
            for a in fs:
                if f <= a:
                    nf = a
                    break
        return nf * step
    delta = nicenum(hi-lo, False)
    return nicenum(delta / (ntick-1), True)


def heckbert(lo, hi, ntick=5, limits=None):
    '''
    Heckbert's "nice numbers" algorithm for graph ranges, from "Graphics Gems".
    '''
    def _heckbert():
        d = heckbert_d(lo, hi, ntick=ntick, limits=limits)
        graphlo = floor(lo / d) * d
        graphhi = ceil(hi / d) * d
        fmt = '%' + '.%df' %  max(-floor(log10(d)), 0)
        value = graphlo
        while value < graphhi + 0.5*d:
            yield fmt % value
            value += d
    return list(_heckbert())

لذلك، على سبيل المثال، إذا كنت تريد عرض الثواني من 0 إلى 60،

>>> heckbert(0, 60, limits=LIM60)
['0', '15', '30', '45', '60']

أو الساعات من 0 إلى 5:

>>> heckbert(0, 5, limits=LIM12)
['0', '2', '4', '6']

من الناحية النظرية، يمكنك أيضًا تغيير مفهومك.حيث لا تكون بياناتك في مركز التصور، ولكن في المركز يوجد مقياسك.

عندما تعرف بداية ونهاية تواريخ بياناتك، يمكنك إنشاء مقياس بكل التواريخ وإرسال البيانات إليك في هذا المقياس.مثل الميزان الثابت.

يمكنك الحصول على مقياس من النوع سنة، شهر، يوم، ساعات، ...وقصر القياس على هذه المقاييس فقط، مما يعني أنك تزيل مفهوم القياس الحر.

الميزة هي إمكانية إظهار فجوات التواريخ بسهولة.ولكن إذا كان لديك الكثير من الفجوات، فقد يصبح ذلك عديم الفائدة أيضًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top