Mpld3: المتصفح / HTML يحدد حجم الشكل بدلاً من حجم الشكل * نقطة في البوصة

تم إنشاؤها على ٦ فبراير ٢٠١٤  ·  31تعليقات  ·  مصدر: mpld3/mpld3

حقا استمتع بالباقة ، شكرا جزيلا للمشاركة.

هذا تحسين مقترح ، لكنه ليس بيثونيًا تمامًا. ولكن بعد ذلك مرة أخرى لا d3js :)

إنه لأمر رائع أن ينعكس الحجم الذي تم تعيينه على الشاشة ، لكنني أعتقد أنه سيكون "أكثر استجابة" أن يكون لديك خيار لتعيين حجم اللوحة على div المحيط ، ثم السماح بتحديد حجم div من خلال عرض المتصفح / أيًا كان آخر المطور يريد.

هل يستحق الأمر أن أتعامل مع _js.py و _object.py حتى يستمر هذا الأمر؟

التعليق الأكثر فائدة

cliffckerr يمكنني بالتأكيد إضافة هذا إلى draw_figure ، ربما كوسيطة تأخذ Object وتعيين جميع السمات المحددة في هذا الكائن على svg ، لذا يمكنك تمرير في شيء مثل {viewBox: ..., width: '90vw', height: 'auto'} .

لم أرغب في سؤالك أنت والآخرين في هذا الموضوع إذا كنت تعتقد أنه يجب إضافة هذا في أي مكان آخر ، لدعم على سبيل المثال fig_to_html() . إذا كان الأمر كذلك ، ربما ينبغي أن نفكر في حل لذلك. بخلاف ذلك ، يُرجى إعلامي ويمكنني إجراء التغييرات على draw_figure() على الفور.

ال 31 كومينتر

لست متأكدًا تمامًا مما تطلبه ... نحصل على حجم الشكل بالبوصة من شكل matplotlib ، وكذلك نحصل على نقطة في البوصة من شكل matplotlib. كيف تقترح علينا تغيير هذا؟ شكرا

بدلاً من استخدام الحجم المطلق للرقم المحدد في Python ، أعني شيئًا كهذا:

<div id='parent' class='figsizeinfo'>
//mpld3 generated code
</div>

حيث يمثل figsizeinfo أحد مواصفة CSS للحجم ، ويملأ mpld3 عنصر div. (من واقع خبرتي هذه هي الطريقة التي يعمل بها flotjs)

حسنًا ... قد يخون هذا السؤال قلة خبرتي في استخدام عناصر الويب ، لكنني اعتقدت أن SVG (الذي يستخدمه mpld3) يعتمد بالكامل على البكسل ، ولا يمكن تغيير ذلك بسهولة. هل تستخدم flotjs SVG أو بعض المواصفات الأخرى؟

رسومات SVG (تنسيق متجه متدرج) تعتمد على المتجهات وليست بالبكسل.

فيما يلي مثال على صورة SVG تم إنشاؤها باستخدام Vanilla matplotlib والتي تتناسب مع حجم النافذة:

http://bleepshow.pithy.io/SVG_Example

(من الواضح أن المثال الخاص بك)

d3js ، وجميع أشكال الرسم القماشية ، متجهة بقدر ما أفهم ، لذا يجب أن يكونوا قادرين على القيام بذلك.

الحيلة ، كما أتخيل ، هي ضبط

figwidth = $(“#parent”).width //(jquery based, but you get the point )

عوضا عن

figwidth = figsize[0] * dpi;

نعم ، أعلم أن SVG يعتمد على المتجهات ، ولكن ما لم أكن مخطئًا ، يتم قياس حجم اللوحة القماشية ، وكذلك حجم العلامات وموضعها على الشاشة بالنقاط. يبدو أنه سيكون من الصعب للغاية كتابة كود SVG الذي سيتم قياسه بشكل صحيح لشكل تعسفي بحجم نافذة تعسفي.

لا ، إنه سهل للغاية.

إليك الاختراق الذي قمت بتطبيقه على كود fig_to_d3 الخاص بك:

print mpld3.fig_to_d3(fig).replace("\n","\r").replace("var figwidth = 8.0 * 80","var figwidth = $(window).width()*.9;").replace("var figheight = 6.0 * 80","var figheight = $(window).height()*.9;")

والذي يأتي على النحو التالي:

http://bleepshow.pithy.io/mpld3_window_scale_test

الآن ، التسميات في المكان الخطأ ، ولكن مرة أخرى إنها "مجرد" مسألة إشارة إلى موضعها إلى div وليس بشكل مطلق إلى الشكل. لكن عرض الشكل يعمل بشكل جيد بقدر ما أستطيع أن أقول.

(لاحظ أن هذا لا يتم تغيير حجمه إلا إذا قمت بالتحديث ، ولكن باستخدام القليل من الغراء الذي يكون أيضًا مستقيمًا للأمام)

أنا حاليًا أقوم بتجهيز حل بناءً على هذا بنفسي ، ويسعدني أن أحاول صقله إلى شيء لائق لطلب السحب.

سيكون الحجم المتجاوب لشكل mpld3 مفيدًا حقًا. إذا أضفت هذا بواسطة زر (في شريط الأدوات) لتتمكن من فتح الشكل الحالي في نافذة جديدة وسيكون الشكل بأكمله قابلاً للتغيير بسهولة.

+1

hadim أريد أن أبقيها "بيثونية" ، لذلك شيء من هذا القبيل

mpld3.fig_to_d3(fig,size="adaptive")

سيكون حافزا جيدا

أنا موافق !

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

تتمثل فلسفة mpld3 في إنتاج مخرجات بسيطة تعكس بأكبر قدر ممكن ما هو موجود في أرقام matplotlib. إذا كنت ترغب في تغيير حجم الشكل الناتج ، فإن الطريقة المفضلة هي ضبط حجم الشكل matplotlib. أي شيء آخر يبدو أنه سيصبح سريعًا مشكلة كبيرة في التنفيذ والاختبار والصيانة.

ماذا عن البرنامج المساعد؟

plugins.connect(fig, plugins.ResponsiveSize())

من المحتمل أن يكون المكون الإضافي طريقة جيدة للقيام بذلك. ولكن مرة أخرى ، كيف تتعامل مع تكييف حجم الخط وعرض الخط وأحجام العلامة ومواقع وسيلة الإيضاح ومواقع نص المحاور؟ بسبب كل هذه المشكلات ، بدون وجود بنية تحتية واسعة لدعم تغيير الحجم ، أعتقد أن مثل هذا المكون الإضافي سيكون له نطاق محدود للغاية من الفوائد.

jakevdp أنا لا أوافق: الشيء الوحيد الذي عانى منه الاختراق لمدة 3 ثوانٍ أعلاه هو مواقع الملصقات ، ومرة ​​أخرى ، إنها مسألة كتابة جافا سكريبت أفضل. يسمح DOM بالتموضع المطلق والموضع النسبي دون بذل الكثير من الجهد.

الطريقة التي يتم بها تنفيذ الكود الآن ، كل شيء ثابت في الشكل. باستخدام القليل من العمل ، يمكن قياس العرض / الارتفاع وسمك الخط وحجم الخط خطيًا مقابل حجم div. الجزء الأصعب سيكون نسبة العرض إلى الارتفاع ، ويمكن قفله. بمجرد قفل نسبة العرض إلى الارتفاع ، يصبح القياس الخطي لكل شيء واضحًا تمامًا

hadim هذه فكرة جيدة.

لا أعرف d3.js لذلك ليس لدي أي فكرة. ولكن لأننا نعمل على ملف svg ، فأنا لا أتخيل حقًا أننا لا نستطيع القيام بذلك بسهولة ...

بعض الروابط لبدء التفكير في أفضل طريقة لتحقيق ذلك:

+1 لـ dansteingart. لماذا لا يتم تعيين طول وموضع SVG الداخلي في الإحداثيات النسبية ، ثم قبل الإخراج ، استخدم viewBox لتغيير حجم الشكل بالكامل وبالتالي المطابقة مع معلمة figsize matplotlib (أو تكون متجاوبة في حالة أخرى).

dansteingart - أوافق على أنه مع وجود عدد كافٍ من الاختراقات JS ، يمكنك جعلها تعمل. ولكن بغض النظر ، فأنا لا أؤيد إجراء تعديل جذري على هذه الحزمة لتضمين هذه الميزة.

لماذا ا؟ حسنًا ، قطعة واحدة هي أنها تتعارض مع فلسفة الحزمة المذكورة أعلاه ، وهي أن عناصر الرسم ، وأحجام الأشكال ، وما إلى ذلك يجب تحديدها من خلال واجهة matplotlib.

ثانيًا ، هذه ليست ميزة "لا بد من امتلاكها" ، وأن جعل قاعدة الشفرة أكثر تعقيدًا بشكل ملحوظ لميزة غير ضرورية سيضر بالحزمة على المدى الطويل. للحصول على بعض المعلومات الأساسية حول سبب حدوث ذلك ، راجع حديث ellisonbg من العام الماضي في SciPy.

إذا كنت ترغب في العمل على مكون إضافي لإضافة هذا النوع من السلوك ، فنحن نرحب بك في. إذا كان يعمل بشكل جيد ، فقد يكون من المفيد تضمينه في الوحدة النمطية plugins . لكنني أعارض بشدة التعديلات الرئيسية على تخطيط الشكل الأساسي للميزات الجديدة التي تتعارض مع فلسفة الحزمة ، بغض النظر عن مدى روعتها.

لقد تعلقت للتو بهذا الأمر ، ويبدو لي أن نوعًا ما من المكونات الإضافية يمكن أن يحقق نوعًا من سلوك تغيير حجم الشكل سريع الاستجابة. بدأ dansteingart هذا الموضوع بفكرة لميزة ، وسؤال حول ما إذا كان الأمر يستحق البدء في تنفيذ الميزة بطريقة معينة. للإجابة على السؤال ، أقترح أن تبدأ بمكوِّن إضافي وترى إلى أي مدى يمكن أن يذهب ذلك دون تغيير _objects.py أو _js.py. ولكن إذا كنت مستعدًا لذلك ، فأنا أود أن أعود خطوة إلى الوراء وأتحدث عن المشكلة التي نحاول حلها:

إنه لأمر رائع أن ينعكس الحجم الذي تم تعيينه على الشاشة ، لكنني أعتقد أنه سيكون "أكثر استجابة" أن يكون لديك خيار لتعيين حجم اللوحة على div المحيط ، ثم السماح بتحديد حجم div من خلال عرض المتصفح / أيًا كان آخر المطور يريد.

أود بعض التوضيحات حول حالة الاستخدام التي سيحدث فيها ذلك. في سير العمل المعتاد ، أستخدم ipython مع خادم كمبيوتر محمول يعمل في السحابة ، مع تكبير متصفح الويب الخاص بي. لذلك يمكن أن يحدث لي إذا قمت بالتبديل من عرض عملي إلى شاشة الكمبيوتر المحمول وكان عرض الشاشة أقل. لكنني متأكد من أن هناك أماكن أخرى يفكر فيها الآخرون. ماذا بعد؟

jakevdp عادل بما فيه الكفاية ، وأنا أوافق على أنه لا ينبغي أن يكون هناك أي تغيير على الإطلاق في جانب الثعبان. ومع ذلك ، أعتقد أنها لعبة عادلة من جانب JS ، وإذا كان الهدف من التجربة هو الزواج من أفضل جوانب matplotlib و d3js ، أعتقد أن الأمر يستحق المتابعة.

بالطريقة التي أراها ، بمجرد استدعاء fig_to_d3 ، فأنت خارج أرض الثعبان ، وتجعل الشكل مستجيبًا = كتابة JS بشكل أفضل.

بالنسبة لفائدة الصفحات المتجاوبة ، بالنسبة لإخراج iPython وحده ، أنا أتفق معك ، لكن Python أكثر من مجرد دفتر iPython ، وأعتقد ، في النهاية ، أن استخدام mpl3d لإنشاء صفحات ويب تستجيب للحجم سيكون أكثر فائدة مما تشير إليه هنا.

وفقًا لمنطقك ، إذا كنت أرغب في تكبير التفاصيل بما يتماشى مع matplotlib ، فيجب أن أقوم فقط بتغيير xlim / ylim.

مرة أخرى ، شكرًا على الحزمة الرائعة ، سأرى ما لا يمكنني فعله باستخدام مكون إضافي وأعود إليك.

تضمين التغريدة

أود بعض التوضيحات حول حالة الاستخدام التي سيحدث فيها ذلك. في سير العمل المعتاد ، أستخدم ipython مع خادم كمبيوتر محمول يعمل في السحابة ، مع تكبير متصفح الويب الخاص بي. لذلك يمكن أن يحدث لي إذا قمت بالتبديل من عرض عملي إلى شاشة الكمبيوتر المحمول وكان عرض الشاشة أقل. لكنني متأكد من أن هناك أماكن أخرى يفكر فيها الآخرون. ماذا بعد؟

انظر http://pithy.io

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

شكرا dansteingart. ضع في اعتبارك أنه على الرغم من إخفاء JS عن مستخدم Python ، إلا أنه لا يزال رمزًا ولا يزال بحاجة إلى الصيانة. تجربتي على مدار السنوات مع تطوير المصادر المفتوحة هي أن الأشخاص غالبًا ما يكونون متحمسين لتطبيق ميزات جديدة ، وبمجرد دمج هذه الميزات ، تقع صيانتها وصيانتها على عاتق عدد قليل من المطورين الذين استثمروا في الحزمة في طويل الأمد. أنا بالفعل شديد الالتزام لدرجة أنني مجبر على تجاهل تقارير الأخطاء على الحزم المستخدمة جيدًا التي أنشأتها منذ بضع سنوات فقط. أنا حقًا لا أريد أن يصل mpld3 إلى هذه النقطة.

شكرًا لتفهمك ، وأتطلع إلى رؤية ما يمكنك تجميعه في مكون إضافي.

jakevdp هذه النقطة مأخوذة جيدًا ، وأعتقد أن بنية البرنامج المساعد تعمل جيدًا لتحقيق هذه الغاية. إذا تعطل ، فسيكون خطأي ، وليس خطأك (أي ما لم تقم بتغيير fig_to_d3 :-p)

لقد وصلت عملية إعادة الكتابة ، وقد يكون هذا _ قليلاً_ أسهل في التنفيذ كمكوِّن إضافي ، على الأقل في المواقف الخاصة. لم أكتبه مع وضع هذا النوع من المواقف الديناميكية في الاعتبار ، لذلك قد يكون هناك بعض المزالق. اسمحوا لي أن أعرف إذا كنت قد أحرزت أي تقدم في هذا الشأن.

مرحبا ، شكرا على المشروع الرائع. هل كان هناك أي تقدم في هذه القضية؟ هل تم تطوير المكون الإضافي / الميزة؟ على وجه التحديد ، أشير إلى "خيار تعيين حجم اللوحة القماشية على div المحيط". شكرا.

أعتقد أن هذه ميزة جديرة بالاهتمام ، ولكن للإشارة بعد التخطيط ، يمكنك استخدام d3 لجعل الشكل مقياسًا تلقائيًا (هنا مع ارتفاع النافذة)

fetch("d3/" + figure + ".json")
    .then((response) => response.json())
    .then((data) => mpld3.draw_figure(figure, data))
    .then(() => {
        d3.select("#" + figure)
            .selectAll(".mpld3-figure")
            .attr("width", "100%")
            .attr("height", "70vh")
            .attr("viewBox", "0 0 1200 800")
            .attr("preserveAspectRatio", "xMinYMin meet");
    });

سأثني هنا على hadim و carlinmack لاستخدام viewBox . يمكن أن يكون بسيطًا جدًا في الواقع. على سبيل المثال ، إذا كان لديك حاليًا <svg width="1200" height="800"> ، فجرّب بدلاً من ذلك <svg viewBox="0 0 1200 800"> . هذا هو. يحدد viewBox النظام الإحداثي داخل svg ، وتصبح المعلمات width و height اختيارية وتحدد الأبعاد الخارجية مثل أي عنصر آخر. يمكنك أيضًا الحصول على width=100% أو تعيين القيمة عبر css مباشرة (العرض والارتفاع مثل css لهما الأسبقية على السمات).

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

ملاحظة: توجد مقالة في الخلفية على https://css-tricks.com/scale-svg لكنني أجدها مربكة عندما تعمل الطريقة التي حددتها أعلاه (على الأقل في المتصفحات الحديثة) وهي بسيطة من الناحية المفاهيمية: viewBox = "0 0 ${width} ${height}" للرمز الداخلي ، width=... و height=... كسمة svg أو معلمة css لإعادة القياس ، إذا لزم الأمر.

حسنًا ، هذا بالضبط ما اقترحه @ carlinmack . لقد كنت مرتبكًا من خلال "استخدام d3 لجعل الشكل مقياسًا تلقائيًا" ، نظرًا لأنه HTML / CSS خالص ، ولكن حسنًا ، التلاعب في DOM هو ما تفعله d3. إن "saveAspectRatio" كما هو مشار إليه بواسطة carlinmack هي القيمة الافتراضية التي أؤمن بها (على الأقل هذا ما تم شرحه في رابط css-tricks.com). لماذا تشير إلى height="70vh" إذا تم الحفاظ على نسبة العرض إلى الارتفاع على أي حال؟ هل هذا نوع من الحد الأعلى للأشكال الضيقة والطويلة جدًا؟

صحيح ، لم أكن أريد أن تكون الأشكال الرأسية أعلى من منفذ العرض :)

إلا أنه يجعل الشكل أكبر من اللازم ، وليس مناسبًا عند الحاجة إلى ملاءمة شديدة مع المحتوى المحيط. يعمل استخدام max-height بدلاً من ذلك بالنسبة لي.

إليك كيف ينتهي بي المطاف بتحميل أرقام mpld3 في المتصفح:

      let figureID = "id_12345" ; 
      let dataURL = figureID + ".json" ; 

      d3.json(dataURL).then( function(data) {
        mpld3.draw_figure(figureID, data);
        return data;
      }).then( function(data) {
        d3.select("#" + figureID)
          .selectAll(".mpld3-figure")
          .attr("width", null)   // remove "width" and "height" attributes as set by mpld3
          .attr("height", null)  
          .attr("viewBox", `0 0 ${data.width} ${data.height}`)
      });

شكرا للمناقشة carlinmackperrette ! من قبيل الصدفة أننا واجهنا هذا أيضًا ، كان حل @ dkong-idm:

    const resizeChart = (viewBoxSettings) => {
        let svg = document.getElementsByClassName("mpld3-figure");

        if (svg && svg.length > 0) {
            svg[0].setAttribute("viewBox",viewBoxSettings );
            svg[0].setAttribute("width", "90vw");
            svg[0].setAttribute("height", "auto");
        }
    }

vladh ، هل سيكون هناك الكثير من العمل لإضافة وظيفة التحجيم التلقائي هذه إلى mpld3 ، إما كحجة اختيارية لـ draw_figure أو كوظيفة قائمة بذاتها؟

cliffckerr يمكنني بالتأكيد إضافة هذا إلى draw_figure ، ربما كوسيطة تأخذ Object وتعيين جميع السمات المحددة في هذا الكائن على svg ، لذا يمكنك تمرير في شيء مثل {viewBox: ..., width: '90vw', height: 'auto'} .

لم أرغب في سؤالك أنت والآخرين في هذا الموضوع إذا كنت تعتقد أنه يجب إضافة هذا في أي مكان آخر ، لدعم على سبيل المثال fig_to_html() . إذا كان الأمر كذلك ، ربما ينبغي أن نفكر في حل لذلك. بخلاف ذلك ، يُرجى إعلامي ويمكنني إجراء التغييرات على draw_figure() على الفور.

vladh نعم ، سيكون مفيدًا أيضًا في fig_to_html() .

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات