求助:使用Dash/Bokeh绘制Python时间线(解决阿拉伯语显示问题)
Got it, let's solve your Arabic text display problem for timelines using Dash and Bokeh—here are practical, working implementations you can adapt:
Dash makes it straightforward to handle right-to-left (RTL) languages like Arabic, as long as you ensure the correct font is loaded. We'll build a timeline with dash_core_components.Graph (powered by Plotly under the hood) and add configurations to support Arabic text.
关键要点:
- Load an Arabic-supporting font (e.g., Noto Naskh Arabic, a free, widely compatible option)
- Set text direction to RTL for Arabic content
- Use Plotly's timeline trace to structure your project data
import dash from dash import dcc, html, Input, Output import plotly.express as px import pandas as pd # 示例阿拉伯语时间线数据 df = pd.DataFrame({ "Task": ["مهمة الأولى", "مهمة الثانية", "مهمة الثالثة"], "Start": ["2024-01-01", "2024-02-15", "2024-03-10"], "Finish": ["2024-01-31", "2024-03-05", "2024-04-01"], "Resource": ["فريق أ", "فريق ب", "فريق ج"] }) app = dash.Dash(__name__) app.layout = html.Div([ html.Div( dcc.Graph(id='arabic-timeline'), style={'direction': 'rtl', 'textAlign': 'right'} ) ]) @app.callback( Output('arabic-timeline', 'figure'), Input('arabic-timeline', 'id') ) def update_timeline(_): fig = px.timeline(df, x_start="Start", x_end="Finish", y="Resource", color="Task") # 配置阿拉伯语文本显示 fig.update_layout( font_family="Noto Naskh Arabic, Arial", title="جدول زمني المشاريع", yaxis_title="الموارد", xaxis_title="التاريخ", title_x=0.5, direction="rtl" ) # 确保阿拉伯语分类顺序正确 fig.update_yaxes(categoryorder='total ascending') return fig if __name__ == '__main__': app.run_server(debug=True)
补充说明:如果你的系统没有预装Noto Naskh Arabic,可以通过CSS加载在线字体。在项目的assets/style.css文件中添加:
@font-face { font-family: 'Noto Naskh Arabic'; src: url('https://fonts.gstatic.com/s/notonaskharabic/v29/xn7YbYvJbagOfGWD8oQzhF4Qs4Bs.woff2') format('woff2'); } body { font-family: 'Noto Naskh Arabic', Arial, sans-serif; direction: rtl; }
Bokeh requires a bit more explicit configuration for Arabic fonts, but it's totally manageable. We'll use bokeh.plotting to create the timeline and set up RTL text rendering properly.
关键要点:
- 指定支持阿拉伯语的字体(如Noto Naskh Arabic,或系统字体"Arial Unicode MS")
- 对阿拉伯语文本使用
text_direction="rtl"参数 - 为坐标轴、标题等元素统一配置阿拉伯语字体
from bokeh.plotting import figure, show, output_file from bokeh.models import ColumnDataSource, LabelSet, DatetimeTickFormatter from bokeh.io import curdoc import pandas as pd from datetime import datetime # 示例阿拉伯语时间线数据 data = { "task": ["مهمة الأولى", "مهمة الثانية", "مهمة الثالثة"], "start": [datetime(2024,1,1), datetime(2024,2,15), datetime(2024,3,10)], "end": [datetime(2024,1,31), datetime(2024,3,5), datetime(2024,4,1)], "y": [1, 2, 3] } source = ColumnDataSource(data=data) # 配置Bokeh文档支持RTL curdoc().theme = 'caliber' p = figure( y_range=["مهمة الأولى", "مهمة الثانية", "مهمة الثالثة"], x_axis_type="datetime", title="جدول زمني المشاريع", width=800, height=400, x_axis_label="التاريخ", y_axis_label="المهام" ) # 添加时间线条形 p.hbar(y='y', left='start', right='end', height=0.5, source=source, color="#2ecc71") # 添加阿拉伯语标签 labels = LabelSet( x='start', y='y', text='task', source=source, text_font="Noto Naskh Arabic", text_direction="rtl", text_align="right", text_baseline="middle", text_font_size="12pt" ) p.add_layout(labels) # 格式化日期坐标轴(可选,适配阿拉伯语日期格式) p.xaxis.formatter = DatetimeTickFormatter( days=["%d/%m/%Y"], months=["%m/%Y"], years=["%Y"] ) # 为所有文本元素设置阿拉伯语字体 p.title.text_font = "Noto Naskh Arabic" p.xaxis.axis_label_text_font = "Noto Naskh Arabic" p.yaxis.axis_label_text_font = "Noto Naskh Arabic" p.yaxis.major_label_text_font = "Noto Naskh Arabic" output_file("arabic_timeline_bokeh.html") show(p)
补充说明:如果你的系统没有安装Noto Naskh Arabic,可以下载字体文件后,在代码中指定完整路径(例如text_font="/path/to/NotoNaskhArabic-Regular.ttf")。
Both of these implementations should handle Arabic text correctly, including right-to-left rendering and proper character shaping. Feel free to tweak the code to match your specific data structure or styling needs!
内容的提问来源于stack exchange,提问作者Tavakoli

