I am trying to convert some figures from *.pdf to *.eps via Inkscape and Python. I resorted to the Inkscape Manual and Inkscape Wiki and came up with the code below. However when I run the script, no output is written into the working directory.
import os
import subprocess
# Change to working directory
os.chdir("C:/Users/Username/Figures")
# Iterate over all PDF figures
for figure in [i for i in os.listdir() if i[-4:]=='.pdf']:
subprocess.run([
"C:/Program Files/Inkscape/inkscape.exe",
figure, # Input figure
f"--export-filename={figure[:-4]}.eps", # Output figure
"--batch-process"
])
There is also a similar question on Stackoverflow. However, if I replace *.emf with *.eps in the answer the files cannot be read by LaTeX.
Update: Inkscape version 0.92.4 (5da689c313, 2019-01-14)
Related
I tried to use ImageDataGenerator to build generator images to train my model, But I am unable to do so because of the PIL.UnidentifiedImageError error. I tried different datasets and the problem pertains only to my dataset.
Now I can't unfortunately delete all the training/testing images as an answer suggested but I can remove the files causing this problem. How can I detect the error causing files?
This is a common problem particularly if you download images from say google. I developed a function that given a directory, it will go through all sub directories and check the files in each sub directory to ensure the have proper extensions and are valid image files. Code is provided below. It returns two lists. good_list is a list of valid image files and bad_list is a list of invalid image files. You will need to have Opencv installed.If you do not have it installed use pip install opencv-contrib-python.
def test_images(dir):
import os
import cv2
bad_list=[]
good_list=[]
good_exts=['jpg', 'png', 'bmp','tiff','jpeg', 'gif'] # make a list of acceptable image file types
for klass in os.listdir(dir) : # iterate through the sub directories
class_path=os.path.join (dir, klass) # create path to sub directory
if os.path.isdir(class_path):
for f in os.listdir(class_path): # iterate through image files
f_path=os.path.join(class_path, f) # path to image files
ext=f[f.rfind('.')+1:] # get the files extension
if ext not in good_exts:
print(f'file {f_path} has an invalid extension {ext}')
bad_list.append(f_path)
else:
try:
img=cv2.imread(f_path)
size=img.shape
good_list.append(f_path)
except:
print(f'file {f_path} is not a valid image file ')
bad_list.append(f_path)
else:
print(f'** WARNING ** directory {dir} has files in it, it should only contain sub directories')
return good_list, bad_list
I am looking for a way to print 3D pdf from the results ABAQUS/Viewer. This will make it easy to communicate the results with others who are interested in the results of simulation but do not have access to ABAQUS.
The best way is to export a vrml file and convert it using Tetra4D or pdf3D and Adobe Acrobat professional. The 3D pdfs can look very good. However, the commercial software would cost over £800 per year. I did create a Python script to create a 3D pdf directly from Abaqus/CAE & Viewer which uses 2 open source tools: 1) Meshlab (http://www.meshlab.net/) to create a U3D file, 2) MiKTeX (https://miktex.org/) to convert the U3D file into a pdf. The output is not as polished as Tetra4D but it works. I have not tried this with the latest version of Meshlab. Just run this script from Abaqus/CAE or Abaqus/Viewer.
# Abaqus CAE/Viewer Python Script to create a 3D pdf directly from Abaqus/CAE or Abaqus/Viewer.
# You must first install meshlab (meshlabserver.exe)and MiKTeX (pdflatex.exe)
# Edit this script to reflect the installed locations of meshlabserver.exe and pdflatex.exe
# It will export a stl or obj file the mesh of current viewport and convert into 3D pdf
# Or run in Abaqus/viewer and it will create a VRML file and convert to 3D pdf.
# If contours are displayed in Abaqus Viewer, then it will create a contour 3D pdf
from abaqus import *
from abaqusConstants import *
from viewerModules import *
import os
import subprocess
import sys
# -----------------------------------------------------------------------------
pdfName='try'
meshlab_path="C:/Program Files/VCG/MeshLab/meshlabserver.exe"
pdfLatex_path="C:/Program Files (x86)/MiKTeX 2.9/miktex/bin/pdflatex.exe"
# -----------------------------------------------------------------------------
currView=session.viewports[session.currentViewportName]
try: # for Abaqus Viewer
cOdbD=currView.odbDisplay
odb = session.odbs[cOdbD.name]
name=odb.name.split(r'/')[-1].replace('.odb','')
module='Vis'
except: # Abaqus CAE
#name=currView.displayedObject.modelName
import stlExport_kernel
name = repr(currView.displayedObject).split('[')[-1].split(']')[0][1:-1] # allows for either main or visulation modules
module='CAE'
print module
if module=='CAE':
#All instances must be meshed
cOdbD=None
try:
ext='.stl'
stlExport_kernel.STLExport(moduleName='Assembly', stlFileName=pdfName + ext, stlFileType='BINARY')
except:
try:
ext='.obj'
session.writeOBJFile(fileName=os.path.join(directory,pdfName + ext), canvasObjects= (currView, ))
except:
print 'Either your assembly is not fully meshed or something else'
directory=(os.getcwd())
else: # Abaqus/Viewer
if cOdbD.viewCut:
session.graphicsOptions.setValues(antiAlias=OFF) # Better with anti aliasing off
odb = session.odbs[cOdbD.name]
directory=odb.path.replace(odb.path.split('/')[-1],'').replace('/','\\')
# Turn off most of the stuff in the viewport
currView.viewportAnnotationOptions.setValues(triad=OFF,
legend=OFF, title=OFF, state=OFF, annotations=OFF, compass=OFF)
ext='.wrl'
session.writeVrmlFile(fileName=os.path.join(directory,pdfName + ext),
compression=0, canvasObjects= (currView, ))
pdfFilePath=os.path.join(directory,pdfName+'-out.pdf')
if os.path.isfile(pdfFilePath):
os.remove(pdfFilePath)
#Check file was deleted
if os.path.isfile(pdfFilePath):
print "Aborted because pdf file of same name cant be deleted. Please close programs which it might be open in"
1/0 #a dodgy way to exit program
# Invoke meshlab to convert to a .u3d file
if cOdbD: #If in Abaqus/viewer
if 'CONTOURS' in repr(cOdbD.display.plotState[0]): # If contours are displayed. Output contoured pdf
p=subprocess.Popen([meshlab_path,'-i',pdfName + ext, '-o',pdfName + '.u3d','-m','vc']) #'vn fn fc vt'
else:
p=subprocess.Popen([meshlab_path,'-i',pdfName + ext, '-o',pdfName + '.u3d'])
else:
p=subprocess.Popen([meshlab_path,'-i',pdfName + ext, '-o',pdfName + '.u3d'])
p.communicate() # Wait for meshlab to finish
file_fullPathName=os.path.join(directory, pdfName + '.tex')
#Read the .tex file which meshlab has just created
with open(file_fullPathName, 'r') as texFile:
lines = texFile.read()
#Edit the .tex file
lines=lines.replace("\usepackage[3D]{movie15}","\\usepackage[3D]{movie15}\n\\usepackage[margin=-2.2in]{geometry}")
if cOdbD:
if 'CONTOURS' in repr(cOdbD.display.plotState[0]):
lines=lines.replace("3Dlights=CAD,","3Dlights=CAD,\n\t3Drender=SolidWireframe,")
lines=lines.replace("\n\end{document}","{---------------------------------------------------------------------------------Click above! MB1 - rotate, MB2 wheel or MB3 - zoom, Ctrl-MB1 - pan--------------}\n\\end{document}")
file_fullPathName=os.path.join(directory, pdfName + '-out.tex')
with open(file_fullPathName, "w") as outp:
outp.write(lines)
p=subprocess.Popen([
pdfLatex_path,
pdfName + '-out.tex',
])
p.communicate()
print 'Conversion to pdf complete'
print file_fullPathName
The simplest way of printing the Abaqus *.odb results are using Tecplot 360 which is read the Abaqus *.odb files and you can get the *.tif and *.png results with any resolutions and you can also rotate the model in 3D and change the fonts and all the things you need.
I am generating a figure using the PS backend:
import matplotlib
matplotlib.use('ps')
from matplotlib import pyplot as plt
plt.plot((1, 2))
I would like to save the figure:
plt.savefig('test.eps', format='eps', bbox_inches='tight', pad_inches=1.0)
Incidentally, I will make a PNG out of it later (in case it turns out to be relevant to the solution):
gs -q -dSAFER -dBATCH -dNOPAUSE -dUseTrimBox -dEPSCrop -sDEVICE=pngalpha -sOutputFile=test.png test.eps
The result is (PNG viewed in eog):
I would like to change the size of the EPS or the PNG figure, but adding a dpi kwarg to savefig does not change the output. Calling plt.gcf().set_size_inches(10, 10) does nothing as well. How do I make my EPS or PNG file have a higher resolution?
This answer is relevant in that it hints that setting dpi for the ps backend may not be the way to go.
Update
For clarification, it is necessary for me to use the PS backend. At the moment, it is the only one that correctly renders LaTeX colored strings. PGF may or may not do what I want, but I do not have time to research its quirks in depth. I was able to get a hacky solution by adding a -r... argument to gs, but would prefer to control everything from MatPlotLib.
If you create the figure with plt.figure first, you can give the figsize-kwarg. An example:
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(10, 1)) # figsize in inches
fig.show() # if running in ipython
# plt.show() # if running as a script with "python script_name.py"
To save with a specific dpi, it should be enough with mentioned dpi-kwarg to the figures savefig-method, i.e.
fig.savefig(..., dpi=300)
Note that if you work with plt to save the figure or to plot, it will always work with the active figure, which might not be the figure you expect if you happen to have several of them opened.
UPDATE
1)
Based on the comment by Mad Physicist, the dpi-kwarg apperently does not work with the PS backend. I do not know why.
I use gnuplot with epslatex option to generate figure files for plotting purposes (like here). Via this method you get 2 files corresponding to same figure, one tex file and one eps file. The figure information is in eps file and font information is in tex file. So my question is this :
Can I combine both font information and figure content to a single file like pdf / eps file ?
UPDATE : OK I forgot to mention one thing. Off course set terminal postscript eps will give me eps outputs, but it will not embed latex symbols in the plot as labels etc.
So I found a method which I got from Christoph's comment. Set terminal like set terminal epslatex 8 standalone and then finally after plotting do something like below:
set terminal epslatex color standalone
set output "file.tex"
set xrange [1:500]
set ylabel "Variance (\\AA\\textsuperscript{2})" # angstoms
set mxtics 4
plot "version1.dat" using 1:3 with linespoints pointinterval -5 pt 10 lt 1 lw 3 title 'label1' , \
"version1.dat" using 1:2 with linespoints pointinterval -5 pt 6 lt -1 lw 3 title 'label2';
unset output
# And now the important part (combine info to single file) :
set output # finish the current output file
system('latex file.tex && dvips file.dvi && ps2pdf file.ps')
system('mv file.ps file.eps')
unset terminal
reset
These steps do output tex file which is converted to dvi and ps file. And finally you rename the postscript file to eps. Now you have figure information and tex symbol information in single file. This eps file is accepted by latex files.
OK now why this works : Sorry I don't know the entire technical details. But this is working fine with me.
I need to output my plots in EPS with the CMYK color space. Unfortunately this particular format is requested by the journal I am submitting my work to!
This discussion was the only one I could find that has addressed the issue but it is more than 2 years old. I was hoping there might be some updates fixing the problem by now.
All my programming is in Python3 and so far I have been saving my plots in PDF which had no problem. But now that I want to plot EPS there is a problem. For example the code bellow prints the simple plot in .png and .pdf but the .eps output is totally blank!
import numpy as np
import matplotlib.pyplot as plt
X=[1,2,3]
Y=[4,5,6]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(X,Y)
fig.savefig('test.eps')
fig.savefig('test.pdf')
fig.savefig('test.png')
So I have two questions:
How can I fix the eps output?
How can I set the eps output color space to CMYK?
Thanks in advance.
I too have the same problem. One workaround I have found is to save plots as .svg and then use a program like Inkscape to convert to eps. I used to be able to save in .eps without any issues and then lost the ability after an update.
Update I was able to solve this problem for my specific setup by changing a few lines in my .matplotlibrc, so I will post the relevant lines here in the hope that it may be helpful to you as well. Note this requires that you have xpdf and ghostscript already installed.
For me the important one was
##Saving Figures
ps.usedistiller : xpdf
But I also have
path.simplify : True
savefig.format : eps
Now I am able to save directly to .eps and include them in LaTeX'ed journal articles...