Published: June 14, 2024
Have you ever had this problem in Matplotlib where the Japanese characters are not properly displayed?
I'm talking about this ugly problem:
Above graph is using Japanese characters for its title, x and y axes labels. As the default font used in Python does not support Japanese characters, they are not printed properly.
And for each character where the program fails to print, a nasty warning message is displayed:
This is a programmer's nightmare.
By the way, above program is created with below code.
import numpy as np
import matplotlib.pyplot as plt
rand_array = np.random.randint(10, size=20)
plt.figure(figsize=(10, 6))
plt.plot(rand_array)
plt.title("晴耕雨読")
plt.ylabel("前人未踏")
plt.xlabel("率先垂範")
plt.show()
Let's go ahead and solve this issue.
Since the deafult font fails to print Japanese characters, we need to change the deafult font to a font that supports Japanese characters.
Let's check what the default font is:
import matplotlib
# Get font family
print(matplotlib.rcParams["font.family"])
# >> ['sans-serif']
# Get fonts within the family
matplotlib.rcParams["font.sans-serif"]
# >> ['DejaVu Sans', 'Bitstream Vera Sans', 'Computer Modern Sans Serif', 'Lucida Grande', 'Verdana', 'Geneva', 'Lucid', 'Arial', 'Helvetica', 'Avant Garde', 'sans-serif']
Unfortunately the current font does not support Japanese characters, however the solution is very simple.
While matplotlib is using the sans-serif
font family as default, there
are many more fonts that can be used, among them the ones which support Japanese.
Let's go ahead and list them:
import matplotlib
fonts = set([f.name for f in matplotlib.font_manager.fontManager.ttflist])
len(fonts), fonts
# >> (303, {'.Aqua Kana', '.Keyboard', '.New York', '.SF Arabic', '.SF Compact', '.SF Compact Rounded', ...
Note that Im using a 2021 model MacBook Pro and these are the available fonts. You might get a different set of fonts depending on the amchine you are using.
Now, let's see which fonts actually do support Japanese in Matplotlib:
import matplotlib
# Matplitlib gives warning when a character cannot be plotted with a font
# We need to escalate it to error so that we can catch it
import warnings
warnings.filterwarnings("error")
# Get all fonts in the OS
fonts = set([f.name for f in matplotlib.font_manager.fontManager.ttflist])
# Initialize a list where we'll keep Japanese compatible fonts
jp_compatible_fonts = []
for i, font in enumerate(fonts):
# Try plotting a text that says: XXフォントが日本語をサポートしているので、大好き!
# Fonts that don't support Japanese will give error
try:
fig = plt.figure(figsize=(0.5,0.5))
plt.text(0, 0, f"{font}フォントが日本語をサポートしているので、大好き!", fontname=font)
plt.axis('off')
plt.draw()
plt.pause(0.001)
# If successfully plotted, add it to the list
jp_compatible_fonts.append(font)
except UserWarning:
pass
# Close the figure so that incompatible font does not influence the next plot
plt.close(fig)
jp_compatible_fonts
# >> ['Apple SD Gothic Neo', 'Hiragino Mincho ProN', 'Arial Unicode MS', 'Heiti TC', 'Hiragino Maru Gothic Pro', 'Hiragino Sans GB', 'Hiragino Sans', 'PingFang HK', '.Aqua Kana']
In my laptop, there were 9 fonts which were able to plot Japanese with no problem:
Let's go ahead and take a look at how these fonts actually plot Japanese:
import matplotlib
fig = plt.figure()
for i, font in enumerate(jp_compatible_fonts):
plt.text(
0,
i,
f"{font}フォントが日本語をサポートしているので、大好き!",
fontname=font,
)
plt.axis("off")
plt.ylim(0, len(jp_compatible_fonts))
plt.show()
Below is the result:
So far, we have found that although the default font in Matplotlib does not plot Japanese characters, there are 9 other fonts which can plot Japanese with no problem. Now let's go back to our original chart.
Before charting though, let's change the deafult font to one of the 9 fonts that we have identified below.
I personally like Hiragino Sans
so I will change the font to it.
import numpy as np
import matplotlib.pyplot as plt
### CHANGE THE FONT FROM DEFAULT TO HIRAGINO SANS
plt.rcParams['font.family'] = "Hiragino Sans"
rand_array = np.random.randint(10, size=20)
plt.figure(figsize=(10, 6))
plt.plot(rand_array)
plt.title("晴耕雨読")
plt.ylabel("前人未踏")
plt.xlabel("率先垂範")
plt.show()
Result is below:
I love how Japanese characters are displayed beautifully, and we don't get a nasty warning anymore.
In this blog post, we have solved the Japanese character display issue in Matplotlib. It is a beautiful solution where just adding 1 more line of code gets rid of the issue.
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = "Hiragino Sans"
The point is to stop using the default font, which does not support Japanese, to a font that actually does. For example, Hiragino Sans, which was readily available on my machine.
Hope you enjoyed this blog post. Let me know if you have any questions or comments below.
Until further notice, happy hacking!
Leave comment
Comments
Check out other blog posts
2024/06/19
Create A Simple and Dynamic Tooltip With Svelte and JavaScript
2024/06/17
Create an Interactive Map of Tokyo with JavaScript
2024/06/13
Book Review | Talking to Strangers: What We Should Know about the People We Don't Know by Malcolm Gladwell
2024/06/07
Most Commonly Used 3,000 Kanjis in Japanese
2024/06/07
Replace With Regex Using VSCode
2024/06/06
Do Not Use Readable Store in Svelte
2024/06/05
Increase Website Load Speed by Compressing Data with Gzip and Pako
2024/05/31
Find the Word the Mouse is Pointing to on a Webpage with JavaScript
2024/05/29
Create an Interactive Map with Svelte using SVG
2024/05/28
Book Review | Originals: How Non-Conformists Move the World by Adam Grant & Sheryl Sandberg
2024/05/27
How to Algorithmically Solve Sudoku Using Javascript
2024/05/26
How I Increased Traffic to my Website by 10x in a Month
2024/05/24
Life is Like Cycling
2024/05/19
Generate a Complete Sudoku Grid with Backtracking Algorithm in JavaScript
2024/05/16
Why Tailwind is Amazing and How It Makes Web Dev a Breeze
2024/05/15
Generate Sitemap Automatically with Git Hooks Using Python
2024/05/14
Book Review | Range: Why Generalists Triumph in a Specialized World by David Epstein
2024/05/13
What is Svelte and SvelteKit?
2024/05/12
Internationalization with SvelteKit (Multiple Language Support)
2024/05/11
Reduce Svelte Deploy Time With Caching
2024/05/10
Lazy Load Content With Svelte and Intersection Oberver
2024/05/10
Find the Optimal Stock Portfolio with a Genetic Algorithm
2024/05/09
Convert ShapeFile To SVG With Python
2024/05/08
Reactivity In Svelte: Variables, Binding, and Key Function
2024/05/07
Book Review | The Art Of War by Sun Tzu
2024/05/06
Specialists Are Dead. Long Live Generalists!
2024/05/03
Analyze Voter Behavior in Turkish Elections with Python
2024/05/01
Create Turkish Voter Profile Database With Web Scraping
2024/04/30
Make Infinite Scroll With Svelte and Tailwind
2024/04/29
How I Reached Japanese Proficiency In Under A Year
2024/04/25
Use-ready Website Template With Svelte and Tailwind
2024/01/29
Lazy Engineers Make Lousy Products
2024/01/28
On Greatness
2024/01/28
Converting PDF to PNG on a MacBook
2023/12/31
Recapping 2023: Compilation of 24 books read
2023/12/30
Create a Photo Collage with Python PIL
2024/01/09
Detect Device & Browser of Visitors to Your Website
2024/01/19
Anatomy of a ChatGPT Response