Matplotlib: Writing right-to-left text (Hebrew, Arabic, etc.)
Asked Answered
M

4

42

I'm trying to add some text to my plot which is RTL (in this case, Hebrew). After some work managed to get it to display the text, but it's displayed LTR (meaning, in the reverese order). I've dug into the reference and did extensive search online and nothing came up.

An example for what I'm using:

import matplotlib.pyplot as plt
plt.text(0.5, 0.5, u'שלום כיתה א', name = 'Arial')
plt.show()

and it displays 'א התיכ םלוש'. In case you can't see the Hebrew, it's as if i'd input 'Hello', and the output would be 'olleH'.

I can't simply reverse the input since it's mixed LTR and RTL.

Every help would be appreciated.

Mesitylene answered 14/3, 2013 at 22:54 Comment(5)
can you have RTL and LTR 'words' separately? Then you could've reversed the RTL ones just before joining them all togetherCentra
do you have the explicit unicode direction characters in the string?Commercial
@Zhenya - no, I can't. They are supplied to my code and not assembled by it.Mesitylene
@tcaswell - I don't know how to check. But if I use python's print the string is displayed correctly, so I guess they are there.Mesitylene
Can you explain, how did you managed to write hebrew in the graph in the first place?Onder
M
33

For whoever encounters the same problem, I found a partial solution.

The bidi package provides this functionality, so using:

from bidi import algorithm as bidialg
import matplotlib.pyplot as plt
text = bidialg.get_display(u'שלום כיתה א')
plt.text(0.5, 0.5, text , name = 'Arial')
plt.show()

displays it correctly.

So why is it partial? Because I found out that the bidi package sometimes messes up latex expression which I use with matplotlib. So use it carefully.

Mesitylene answered 16/3, 2013 at 12:16 Comment(1)
hi, when I try this all non-English letters get displayed as blank squares and the following error message gets generated: /usr/local/anaconda3/lib/python3.5/site-packages/matplotlib/font_manager.py:1288: UserWarning: findfont: Font family ['Arial'] not found. Falling back to Bitstream Vera Sans (prop.get_family(), self.defaultFamily[fontext])) It seems I need to install new fonts but all of my tries have been failed to do so. Do you have any suggestion?Dorsey
A
63

For Arabic you need both bidi.algorithm.get_display and arabic_reshaper modules:

from bidi.algorithm import get_display
import matplotlib.pyplot as plt
import arabic_reshaper

reshaped_text = arabic_reshaper.reshape(u'لغةٌ عربيّة')
artext = get_display(reshaped_text)

plt.text(0.25, 0.45, artext , name = 'Times New Roman',fontsize=50)
plt.show()

python matplotlib arabic text

Anaerobic answered 30/12, 2014 at 9:28 Comment(0)
M
33

For whoever encounters the same problem, I found a partial solution.

The bidi package provides this functionality, so using:

from bidi import algorithm as bidialg
import matplotlib.pyplot as plt
text = bidialg.get_display(u'שלום כיתה א')
plt.text(0.5, 0.5, text , name = 'Arial')
plt.show()

displays it correctly.

So why is it partial? Because I found out that the bidi package sometimes messes up latex expression which I use with matplotlib. So use it carefully.

Mesitylene answered 16/3, 2013 at 12:16 Comment(1)
hi, when I try this all non-English letters get displayed as blank squares and the following error message gets generated: /usr/local/anaconda3/lib/python3.5/site-packages/matplotlib/font_manager.py:1288: UserWarning: findfont: Font family ['Arial'] not found. Falling back to Bitstream Vera Sans (prop.get_family(), self.defaultFamily[fontext])) It seems I need to install new fonts but all of my tries have been failed to do so. Do you have any suggestion?Dorsey
A
7

You can try to flip the text by :

import matplotlib.pyplot as plt
plt.text(0.5, 0.5, (u'שלום כיתה א')[::-1], name = 'Arial')
plt.show()

Adige answered 24/8, 2020 at 16:42 Comment(1)
I used your solution, and it worked for me! I just added a check to see if these are non-Latin letters: from string import printable if bool(set(text) - set(printable)): text = text[::-1]Bignonia
F
3

I had the same issue and i think that using both answers of @Korem and @Nasser Al-Wohaibi like:

import arabic_reshaper
from bidi.algorithm import get_display

new_text=get_display(arabic_reshaper.reshape(old_text))

because only the arabic_reshaper didnt rearrange the letters and the bidi only didn't combine them

^_^

Fantom answered 28/11, 2019 at 17:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.