plotly / plotly/plotly.py

Add support for internationalization of multilingual figures

Đang mở
#2,475 2 bình luận 2 reaction 1 người được giao Xem trên GitHub

@T4rk1n đang làm issue này rồi.

Từ ngày 8/7/2024.

feature P3
Ngôn ngữ chính
Python
Star
18.8k
Fork
2.8k
Merge trung bình
16 giờ 26 phút
Pull request đã merge (30 ngày)
21

Mô tả

Hello! This feature request comes from a project that uses Dash, but the problems/changes are in plotly modules so I opened the ticket here.

Context: The goal is to render a dashboard with various figures (graphs and maps) in different languages. At the moment, it is required to build 4 Dash layouts to serve 4 languages, making development less convenient (can’t use standard translation tools) and requiring 4 times the memory for hosting (this was profiled). I am not the author of the project, but for a hackathon I looked at using the Flask i18n extension, and found out that Dash is not directly compatible; then after finding a compat trick, I found out that it wasn‘t enough.

Details:
This is a Dash app https://github.com/jeremymoreau/covid19mtl/blob/master/app/__init__.py viewable at https://covid19mtl.ca/en . (It’s not using latest plotly or dash for stability or familiarity I suppose.)

1) I looked for Flask i18n guides and tried to add Flask-i18n which uses a classic gettext approach with a LazyString class that is rendered to a localized string at request time.

https://github.com/jeremymoreau/covid19mtl/pull/21/files#diff-1f9f743421417fb2794c88447083a031R12-R27

LazyString was rejected during JSON encoding. I looked at this method https://github.com/plotly/plotly.py/blob/v4.6.0/packages/python/plotly/_plotly_utils/utils.py#L100 which led me to define as_plotly_json https://github.com/jeremymoreau/covid19mtl/pull/21/files#diff-828aeb2697b4cf1e4ba7120b38810cccR5-R9 to be compatible, and it worked for Dash HTML components (example https://github.com/jeremymoreau/covid19mtl/pull/21/files#diff-4599052b1ffcd344c72d72ce59a64186R399 — this is in template.py file that github hides by default even if there is a line link ☹️)

Now, how to upstream this? plotly doesn’t know about flask, but dash itself doesn’t transform to JSON, that code is in _plotly_utils and is not extensible, so I couldn’t send a quick PR. «Not extensible» I mean that a list of conversion functions is hard-coded and tried in order. Other approaches like Pyramid’s adapters or https://pypi.org/project/json-encoder/ based on single-dispatch can be extended from downstream code. But these rely on types (object class), whereas the existing approach checks for the presence of attributes (special method like tolist) or special values (pandas funky NaN and such).

Would you be open to reworking this? I think a hybrid approach could work (detect special methods like as_plotly_json or fancy scipy stack objects first, then delegate to a single-dispatched function that checks types to handle datetime, decimal, etc, and expose that function so that Dash can register a conversion function for the LazyString type.

2) The LazyString class is rejected by checks in plotly figure classes, so we can’t translate all the labels. This blocked my efforts. I didn’t try to make a str subclass because built-in classes often have shortcuts in codebases (starting with CPython itself!) so your overriden methods are not getting called when you expect and it’s a dead end. We didn’t try applying translations using JavaScript because it would require to write more gettext integration, and some of the labels are inside SVG sub-documents which wouldn’t be easy to get.

How can we satisfy plotly type checks when passing a custom class that should be transformed (i.e. call str) at render time?

Thanks for reading and considering this! I am sure more than one person would like to make multilingual plots and dashboards, so it would be great if I could contribute some useful code upstream.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.