4

I tried

import locale
locale.setlocale(locale.LC_TIME,'en_US')
tyme = [datetime(2009,10,6,12) + timedelta(hours=6*i) for i in range(5)]
plt.contour(x, tyme, data)
ax=plt.gca()
ax.yaxis.set_major_formatter(matplotlib.dates.DateFormatter('%Hz%d%b'))

but yaxis labels are ploted not like 00Z07Oct but 00Z0710□ (probably ploted in my language environment, Japanese, and the characters are garbled.)

On the other hand, I tried,

 import locale
 locale.setlocale(locale.LC_TIME,'en_US')
 print datetime(2009,10,7,0).strftime(''%Hz%d%b)

the result is

00z07Oct

This works well.

How can I set matplotlib.dates.DateFormatter for English in different language environment? Any help would be appreciated.

2 Answers2

2

I suspect this has to do with unicode issues, in particular matplotlib.cbook.unicode_safe(). This function is actually run inside DateFormatter on the output of strftime. Try setting the local for everything to see if it helps:

locale.setlocale(locale.LC_ALL,'en_US')

If it doesn't, just define a new DateFormatter that doesn't have the cbook.unicode_safe() call:

return cbook.unicode_safe(dt.strftime(fmt))

replaced by:

return dt.strftime(fmt)
tiago
  • 22,602
  • 12
  • 72
  • 88
  • Thank you for answering my question. Unfortunately, your both solutions do not work well. Do you know how to set matplotlib's default locale ? –  Jan 22 '13 at 04:22
  • Sorry to hear that none of this worked. Are you sure that if you define a new `DateFormatter` with the only difference mentioned it doesn't work? From your remark that `datetime(2009,10,7,0).strftime('%Hz%d%b')` gave the right string I would've thought it worked. But sadly I can't replicate your problem, so I can't really check if the solutions work. Matplotlib doesn't really have a locale, but there is a configuration called `axes.formatter.use_locale` that if `True` will use the system's locale. For the axes formatter (but looking at the source code it doesn't seem to help you if set). – tiago Jan 22 '13 at 14:46
  • Yes, I replaced `cbook.unicode_safe(dt.strftime(fmt))` by `dt.strftime(fmt)` in dates.py. It is strange that trying `locale.setlocale(locale.LC_ALL,'en_US')` on other PC, it works well. When I directly write `locale.setlocale(locale.LC_ALL,'en_US')` in DateFormatter class code, this also works well on the both PCs. –  Jan 22 '13 at 17:59
  • I want to show `Persian` month in `x-axis` of my `matplotlib` plot. I used `locale.setlocale(locale.LC_ALL,'fa_IR')`, but it only changed the name of `georgian` months from English to persian instead of showing `Persian` month names which are known as `Jalali`. any ideas? – Shahriar.M Aug 12 '20 at 05:15
  • @Shahriar.M you need something like [`jdatetime`](https://pypi.org/project/jdatetime/), but I don't know if matplotlib can use it internally. Maybe the easiest solution is to manually set the formatter. – tiago Aug 13 '20 at 11:40
  • @tiagoI used `jdatetime` [here](https://stackoverflow.com/questions/63356748/is-there-a-way-to-show-persian-date-in-x-axis-of-matplotlib-plot), but, as you mentioned, `matplotlib` is not compatible with it. Can you please give me a clue about how to set the formatter? – Shahriar.M Aug 13 '20 at 13:55
  • I struggled with this for an hour, until I found that I have to call `locale.setlocale(locale.LC_TIME, 'en_GB')` **after** the plot has started for it to work (with `matplotlib.dates.DateFormatter()`). Note the emphasis on **after**. – AstroFloyd Apr 01 '22 at 15:43
1

Insert:

locale.setlocale(locale.LC_TIME,'en_US')

or:

locale.setlocale(locale.LC_ALL, "en_GB.utf8")

inside your figure.

If this does not work, try to define format before figure. E.g.

import locale
dfmt = dates.DateFormatter('%Hz%d%b')
...
locale.setlocale(locale.LC_ALL, "en_GB.utf8")
ax.yaxis.set_major_formatter(dfmt)
Michal
  • 11
  • 1
  • None of them work for [my problem](https://stackoverflow.com/questions/63356748/is-there-a-way-to-show-persian-date-in-x-axis-of-matplotlib-plot). they just show months name in `Persian` alphabets instead of using `Persian` month names. – Shahriar.M Aug 12 '20 at 05:36