matplotlib generated PDF cannot be viewed in acrobat reader - python

I am plotting data with matplotlib including LaTeX fonts. The pdf created can be displayed by evince, inkscape, GIMP but not by acroread resp. adobe reader. The code prototype works with a lot of figures and only a few plots have this problem.
...
fig = plt.figure(figsize=(10, 6))
ax = fig.add_subplot(111)
savedpi = 250
fileformat = 'pdf'
...
p12,=ax.plot(plimit12-binSize/2.0, mean12, '-', lw=2)
ax.set_yscale('log')
ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())
ax.legend([p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12], [ "C01", "C02", "C03", "C04", "C05", "C06", "C07", "C08", "C09", "C10", "C11", "C12"],numpoints=1, loc=1, ncol=3)
plt.savefig(savepath+'veloDisp'+'.pdf',dpi=None,format=fileformat)
One of these problematic files is to be fount at http://ubuntuone.com/0kuZIKYeZQyGckE5jonPy6
Did anyone encounter such a problem?
EDIT: Thank you William Denman, in fact opening in evince and printing into pdf works, it can be viewed in acroread as well now. Interestingly, other plots with LaTeX Fonts work from the get go. I do not get any error messages from which I could guess where the problem lies, this is why I asked here in the first place. For now your workaround is fine, thank you. However I would really like to know how this can be avoided generally. As these plots should be part of a publication, I have to think also about those people using Adobe pdf viewers.
EDIT: As suggested, I opened a thread on the MPL developers mailing list, see http://matplotlib.1069221.n5.nabble.com/PDF-not-readable-by-Adobe-PDF-readers-td42580.html
EDIT: Solved by matplotlib developers! The problem was the line
ax.axvline(x=1, c='#000000', lw='2', alpha=0.5)
which contains a string as line width. Should be
ax.axvline(x=1, c='#000000', lw=2, alpha=0.5)
Unfortunately standard pdf backend does not warn about this (yet).

After chasing my own bug in matplotlib I figured out based on this post and the referral the OP makes at matplotlib site that chasing bugs in matplotlib can be done with cairo. pip install cairo. Then on top of all other MPL imports add:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import ...
import matplotlib
matplotlib.use("cairo")
from matplotlib.backends.backend_pdf import PdfPages
..etc.
otherwise the chase will fail because the backend is already set and loaded....

Related

Could Google Colab display Traditional Chinese fonts except "TaipeiSansTCBeta" in Matplotlib plots?

To whom it may concern:
Thank you for your time.
Here are some codes about drawing a matplotlib plot with Traditional-Chinese labels and legends which can work well in Colab.
import matplotlib as mpl,matplotlib.font_manager as mf,matplotlib.pyplot as plt
!wget -O TaipeiSansTCBeta-Regular.ttf https://drive.google.com/uc?id=1eGAsTN1HBpJAkeVM57_C7ccp7hbgSz3_&export=download
mf.fontManager.addfont('TaipeiSansTCBeta-Regular.ttf')
mpl.rc('font',family='Taipei Sans TC Beta')
lg=("明度高","\n亮度高","頻率高","\n摩擦力小","密度大")
xt=("純墨條","高筋麵粉","在來米粉","鹽","洗碗精","小蘇打粉","酵母")
a=(-1.06166376,-2.56410256,-15.21126761,-19.04761905,35.2941176470)
b=(0,0,-9.15492958,-42.85714285714285714,29.4117647058)
c=(-6.67539267,-15.38461538,-45.49295775,-47.61904762,17.6470588235)
d=(-9.08958697,-20.5128205,15.21126761,9.52380952,11.7647058823)
e=(-7.86794648,-17.94871795,0,-17.94871795,11.7647058823)
f=(-3.25770797,-7.69230769,-6.05633803,-52.38095238,-5.882352941176)
x=(0,0,0,0,0)
yd=(x,a,b,c,d,e,f)
fig,ax=plt.subplots(figsize=(4,5),dpi=300)
for i in range(0,len(xt)):
ax.plot(lg,yd[i],label=xt[i],marker="o")
ptxk=["x-large","k"]
ax.tick_params(axis="x",labelsize=ptxk[0],colors=ptxk[1])
ax.tick_params(axis="y",labelsize="small")
ptt=["『定期定額』vs『定期定額逢低加碼』","x-large","k"]
ptlyl=["各\n變\n因\n較\n無\n添\n加\n墨\n百\n分\n比\n變\n化\n率\n(%)","x-large","darkcyan"]
plt.title(ptt[0],fontsize=ptt[1],color=ptt[2],y=-0.25)
ax.set_ylabel(ptlyl[0],fontsize=ptlyl[1],color=ptlyl[2],rotation=0)
ax.set_yticks([*range(-50,71,10)])
ax.yaxis.set_label_coords(-0.17,0.05)
ax.legend(fontsize="large")
ax.set_axisbelow(True)
plt.grid()
plt.show()
The words in labels and legends only work well with the font called "TaipeiSansTCBeta" like the following picture.
(https://i.stack.imgur.com/CJfas.png)
Could the font be changed to another one like "DFKai-SB", or it only supports "TaipeiSansTCBeta"?
Some information on the internet about this is to add the codes below to line 2, and delete the codes about !wget, font_manager, and mpl.rc. But it doesn't work at all by displaying blank blocks.
mpl.rcParams['font.family'] = 'DFKai-SB'
(https://i.stack.imgur.com/EmMdL.png)
Would you please inform some demonstrations about the problem, or giving some clues to figure out how it works?
So far haven't found any answer to change to another Chinese font in Colab with matplotlib. It's highly appreciate for your guidance.
Best wishes and great thanks,
wish you have a happy new year.

Matplotlib version of latex command "\ell" looking extra-slanted

I use latex in matplotlib by setting
plt.rcParams.update({'mathtext.fontset': 'stix'})
plt.rcParams.update({'font.family': 'STIXGeneral'})
I am using the letter $\ell$ very often in my research and there is a small detail bothering me. As you can see below, matplotlib renders the symbol with the little loop smaller and the letter more slanted. To me it almost looks like a vertically stretched $e$. I tried using the "\mathrm{\ell}" command instead but it did not change anything.
Is there any way I could get the symbol to look normal?
PS: it looks like stackoverflow is not detecting the math mode $ for some reason. If you know how to fix it (or if I am doing something wrong) please point it out or edit the question. Thanks!
The reason is the font you are using in matplotlib. With the following settings, for example, you get the same letter as in overleaf:
import matplotlib.pyplot as plt
import numpy as np
# Example data
t = np.arange(0.0, 10, 1)
s = np.arange(0.0, 10, 1)
plt.rc('text', usetex=True)
plt.rc('font', family='serif')
plt.xlabel(r'$\ell$', fontsize=30)
plt.ylabel(r'$\ell$', fontsize=30)
plt.plot(t, s)
plt.show()
You get:
However, In Jupyterlab I could not reproduce. It used the overleaf fonts even with your settings.
This proved to be the simplest solution for me. Thanks the others for pointing out the font being the issue.
Rather than
plt.rcParams.update({'mathtext.fontset': 'stix'})
plt.rcParams.update({'font.family': 'STIXGeneral'})
I now write the first line as
plt.rcParams.update({'mathtext.fontset': 'cm'})
which works like charm. This is helpful if you are someone like me not using TeX but just the mathtext matplotlib built-in function.

Latex font in matplotlib - Script-r

In matplotlib, one can easily use latex script to label axes, or write legends or any other text. But is there a way to use new fonts such as 'script-r' in matplotlib? In the following code, I am labelling the axes using latex fonts.
import numpy as np
import matplotlib.pyplot as plt
tmax=10
h=0.01
number_of_realizations=6
for n in range(number_of_realizations):
xpos1=0
xvel1=0
xlist=[]
tlist=[]
t=0
while t<tmax:
xlist.append(xpos1)
tlist.append(t)
xvel1=np.random.normal(loc=0.0, scale=1.0, size=None)
xpos2=xpos1+(h**0.5)*xvel1 # update position at time t
xpos1=xpos2
t=t+h
plt.plot(tlist, xlist)
plt.xlabel(r'$ t$', fontsize=50)
plt.ylabel(r'$r$', fontsize=50)
plt.title('Brownian motion', fontsize=20)
plt.show()
It produces the following figure
But I want 'script-r' in place of normal 'r'.
In latex one has to add the following lines in preamble to render 'script-r'
\DeclareFontFamily{T1}{calligra}{}
\DeclareFontShape{T1}{calligra}{m}{n}{<->s*[2.2]callig15}{}
\DeclareRobustCommand{\sr}{%
\mspace{-2mu}%
\text{\usefont{T1}{calligra}{m}{n}r\/}%
\mspace{2mu}%
}
I don't understand how to do this in matplotlib. Any help is appreciated.
Matplotlib uses it's own hand-rolled (pure Python) implementation of TeX to do all of the math text stuff, so you absolutely cannot assume that what works in standard LaTeX will work with Matplotlib. That being said, here's how you do it:
Install the calligra font so that Matplotlib can see it, then rebuild the font cache.
Lots of other threads deal with how to do this, I'm not going to go into detail, but here's some reference:
Use a font installed in a random spot on your filesystem.
How to install a new font into the Matplotlib managed font cache.
List all fonts currently known to your install of Matplotlib.
Replace one of Matplotlib's TeX font families with your font of choice.
Here's a function I wrote a while ago that reliably does that:
import matplotlib
def setMathtextFont(fontName='Helvetica', texFontFamilies=None):
texFontFamilies = ['it','rm','tt','bf','cal','sf'] if texFontFamilies is None else texFontFamilies
matplotlib.rcParams.update({'mathtext.fontset': 'custom'})
for texFontFamily in texFontFamilies:
matplotlib.rcParams.update({('mathtext.%s' % texFontFamily): fontName})
For you, a good way to use the function would be to replace the font used by \mathcal with calligra:
setMathtextFont('calligra', ['cal'])
Label your plots, for example, r'$\mathcal{foo}$', and the contents of the \math<whatever> macro should show up in the desired font.
Here's how you'd change your label-making code:
plt.ylabel(r'$\mathcal{r}$', fontsize=50)
and that should do it.

displaying charts from python executables in shell

I'm using python 2.7 on Ubuntu to draw charts from text files containing data.
My point is, when using python executables in shell, I have no problem recording plots, but if I want them shown on my screen instead I have to go through the graphic interface. If possible, I would very much like to skip that part and get a dynamic display that I can interact with (as if I were to run my script from a python shell)!!
a MWE of what i'm doing is :
MWE
import numpy as np
import matplotlib.pyplot as plt
with open('filename','r') as myfile:
DATA = np.genfromtxt(myfile,unpack=True)
fig = plt.figure()
... my plot configuration ...
plt.savefig("image_name"+'.png')
plt.close()
end of MWE
Using this script image_name.png appears in my repertory. I tried replacing the last 2 lines with plt.plot() and plt.draw() but nothing happened.
Many thanks!
Michel
(edited)

EPS created with matplotlib does not show text correctly

I have a Font problem in eps-files from matplotlib.
The font show correctly in die eps file, but when I paste the file in Microsoft Word, it doesnt Show the text (Labels, ticks, title...)
I already tryed to change the maplotlib.rcParams because that was the solution for other problems with text in eps files, but nothing worked.
EDIT: already changed matplotlib.use("xxx") too, did not help.
my code:
# -*- coding: utf-8 -*-
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
fig = plt.figure(figsize=(12,10))
ax = fig.add_subplot(111, projection='3d')
plt.title("lalala",family='Courier New')
x = range(len(a))
y = range(len(a))
X,Y = np.meshgrid(x,y)
Z = a
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.plot_surface(X,Y,Z, cmap=plt.cm.Reds, cstride=1, rstride=1,alpha=0.3)
plt.savefig("texttestqua.eps")
plt.show()
is it possible to "draw" the text in the eps file? So that the text is not a "font" but just graphic-vectors?
I am not entirely sure if your problem stems from the inability of matplotlib to save your eps correctly or the inability of Microsoft Word to load vector graphics other than emf/wmf...
Nonetheless, I am giving it a try...
There are quite a lot of backends (GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo CocoaAgg MacOSX Qt4Agg Qt5Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG), have you tried them all or at least a plausible subset?
Does it work for example with PS?
I am using the TkAgg backend here and your script produces the following output for me:
but when I paste the file in Microsoft Word, it doesnt Show the text (Labels, ticks, title...)
Afaik Microsoft Word does not support vector graphics natively unless it is emf. See this link for further guidance.
If that does not solve your problem, please consider formulating an explicit problem.

Categories

Resources