python-pillow / Pillow

Python Imaging Library (Fork)
https://python-pillow.org
Other
12.32k stars 2.23k forks source link

Tamil font is rendered in a wrong manner in matplotlib #8481

Closed GitPavan123 closed 1 month ago

GitPavan123 commented 1 month ago

I have been working on with a project in matplotlib. I'm trying to display tamil texts in a pie chart. I did downloaded and specified the appropriate font paths (In my case Brahmini, Noto sans tamil, Tiro, etc...) Everything does render the tamil font but it is completely in a wrong manner. Figure(1) is the actual rendering. Figure(2) is the required rendering.

CODING

import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

font_path = r"Fonts\Tamil Font.TTF" //Replace with a tamil font path

tamil_font = FontProperties(fname=font_path) 

sizes = [25, 35, 20, 20]  
labels = ['எனக்கு ', 'மின்விசிறி', 'கலை', 'வாழைப்பழம்']  
colors = ['#ff9999','#66b3ff','#99ff99','#ffcc99']

fig, ax = plt.subplots()
wedges, texts, autotexts = ax.pie(sizes, colors=colors, autopct='%1.1f%%', startangle=90)

ax.axis('equal')

for i, autotext in enumerate(autotexts):
    autotext.set_text(labels[i])  
    autotext.set_color("black")  
    autotext.set_fontsize(12)  
    autotext.set_fontproperties(tamil_font)  

for text in texts:
    text.set_fontproperties(tamil_font)

plt.show()

Screenshot 2024-10-18 024111 image

radarhere commented 1 month ago

Hi. Do you have raqm installed?

>>> from PIL import features
>>> features.check("raqm")
True
GitPavan123 commented 1 month ago

No what is it's used for?

radarhere commented 1 month ago

Complex text rendering. It is "recommended for all non-English text". See https://github.com/python-pillow/Pillow/issues/6018#issuecomment-1030893495 for an instance where using Raqm has solved Tamil rendering in the past.

How did you install Pillow?

If you're a Windows user, I suggest looking at https://pillow.readthedocs.io/en/stable/installation/building-from-source.html

On Windows this requires compiling FriBiDi and installing fribidi.dll into a directory listed in the Dynamic-link library search order (Microsoft Learn) (fribidi-0.dll or libfribidi-0.dll are also detected).

GitPavan123 commented 1 month ago

I installed pillow in my conda environment using the command "pip install pillow". But even though i upgrade my pillow version still it returns false for the checking the existence of raqm.

radarhere commented 1 month ago

What operating system are you using?

Could you uninstall Pillow, and then run pip install -v Pillow and show us the output?

GitPavan123 commented 1 month ago

I am using windows os

radarhere commented 1 month ago

Have you attempted placing fribidi in the correct location? Here is fribidi.dll from our recent Pillow 11.0.0 release for various architectures - fribidi.zip

https://pillow.readthedocs.io/en/stable/installation/building-from-source.html

On Windows this requires compiling FriBiDi and installing fribidi.dll into a directory listed in the Dynamic-link library search order (Microsoft Learn) (fribidi-0.dll or libfribidi-0.dll are also detected).

GitPavan123 commented 1 month ago

I have installed raqm and now i get true for the following code,

>>> from PIL import features
>>> features.check("raqm")

Now how do i enable or activate raqm to render text in matplotlib pie chart?

radarhere commented 1 month ago

Hmm. I would have expected the correct output from matplotlib once you had done that.

If matplotlib is still not working as you expect, does the following Pillow-only code work?

from PIL import Image, ImageDraw, ImageFont

font = ImageFont.truetype(r"Fonts\Tamil Font.TTF", 25)

im = Image.new("RGB", (250, 250))
draw = ImageDraw.Draw(im)

for i, text in enumerate(['எனக்கு ', 'மின்விசிறி', 'கலை', 'வாழைப்பழம்']):
    draw.text((20, 20+i*50), text, font=font, fill="white")
im.show()
GitPavan123 commented 1 month ago

The provided code does give the correct output but in matplotlib it is not outputting correctly

radarhere commented 1 month ago

Ok, so we are agreed that Pillow by itself is behaving correctly.

Can I ask - what led you to the conclusion that incorrect matplotlib output was caused by Pillow? Searching through the matplotlib main, I see no calls to truetype() or FreeTypeFont.

https://github.com/matplotlib/matplotlib/issues/5941#issuecomment-176474866 says

Matplotlib uses its own basic text layout algorithm, rather than something like Pango, which can handle internationalized text. This is the main purpose of MEP14

MEP14 is https://matplotlib.org/devdocs/devel/MEP/MEP14.html

https://github.com/matplotlib/matplotlib/issues/23082 indicates that using https://github.com/matplotlib/mplcairo might be the solution.

GitPavan123 commented 1 month ago

Can you please tell me indepth about setting up mpl cairo backend to overcome the issue

radarhere commented 1 month ago

Could you

  1. pip install mplcairo
  2. Add the following to the beginning of your Python script?
    
    import matplotlib
    matplotlib.use("module://mplcairo.tk")

Once your code is working, this can be removed.

It is just to force an error to be raised if raqm cannot be found

import mplcairo mplcairo.set_options(raqm=True)



Then try to run your script again. If an error is displayed, please let us know what it is.
GitPavan123 commented 1 month ago
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt
import mplcairo
import matplotlib

matplotlib.use("module://mplcairo.tk")

mplcairo.set_options(raqm=True)

font_path = r"Fonts\Tamil Font.TTF"

tamil_font = FontProperties(fname=font_path)

plt.title('எனக்கு', fontproperties=tamil_font)

plt.show()

with this code i get the following error,

(.venv) C:\Users\pavan\StudioProjects\UK_Client>python temp.py
Traceback (most recent call last):
  File "C:\Users\pavan\StudioProjects\UK_Client\temp.py", line 10, in <module>
    mplcairo.set_options(raqm=True)
OSError: [WinError 126] The specified module could not be found

mplcairo is installed successfully and so fribidi and raqm as well

radarhere commented 1 month ago

mplcairo README says

the directory containing libraqm.dll and libfribidi-0.dll need to be added to the DLL search path

I can tell you that on my macOS machine, the result is correct.

Screenshot 2024-10-22 at 6 57 22 am

How to get it up and running on Windows is really a question for https://github.com/matplotlib/mplcairo. They will have the proper expertise to help you out.

nulano commented 1 month ago

libraqm.dll and libfribidi-0.dll

I'd wager a guess that these are the libs that cgohlke was providing for Pillow before #5062 was merged. Actually, looking at the readme, it specifically links to the page that used to host cgohlke's Pillow builds.

But yes, this is a question for mplcairo, not Pillow, especially since we no longer use or build libraqm.dll.