Python Save Multiple Figures in same PDF - python

Im trying to save Figures to the same PDF file. The document is created however the figures is acting odd. I have created 3 Figures in 3 different windows.
If i save them seppretly it work but when I save all three figures the only thing that show in the PDF is three figures of Figure_3.
Is there a smart way of doing this?
Thanks in advance!
from matplotlib.backends.backend_pdf import PdfPages
pp = PdfPages('Output.pdf')
pp.savefig(Figure_1)
pp.savefig(Figure_2)
pp.savefig(Figure_3)
pp.close()
My code for the figures are:
ax = plt.axes(xscale='log', yscale='log')
Figure_1 = ax.plot(Time, Data1, label = Data1)
Figure_2 = ax.plot(Time, Data2, label = Data2)
Figure_3 = ax.plot(Time, Data3, label = Data3)

Related

Specified color looks different when saved as pdf

I am plotting something with a hatched area. However, when saving it as a .pdf the color is different from what I specified it. In the console it is displayed correctly and also when saving as a .png file it shows the correct color. I am wondering if this has been observed before and if someone knows a workaround / fix for this or if I am doing something wrong.
This is what I want the picture to look like:
This is what it looks like in the pdf:
As you can see the hatching works fine for all peaks except the red one. In the pdf the hatching is gray instead of red. Also the colors in the pdf seem to be more transparent than in the png.
I am using matplotlib version 3.2.2.
For reproduction here is my code:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from matplotlib.ticker import MultipleLocator
def gauss(x,mu,sigma,a):
return a*np.exp(-(x-mu)**2/(2*sigma**2))
x = np.linspace(0,10,1000)
data1 = gauss(x,6.5,0.5,10)
data2 = gauss(x,3,0.8,15)
data3 = gauss(x,5,0.2,12)
data4 = gauss(x,8,0.4,11)
data = data1 + data2 + data3 + data4
fs = 20
ls=20
plt.figure()
ax = plt.gca()
plt.plot(x,data,'k.',mfc='none',label='Data')
plt.plot(x,data,'r')
plt.fill(x,data1,'gold',ec='darkgoldenrod',label='1')
plt.fill(x,data2,'crimson',ec='darkred',hatch='//',alpha=0.5,label='2')
plt.fill(x,data3,'mediumslateblue',ec='b',hatch='\\\\' , alpha=0.5,label='3')
plt.fill(x,data4,'limegreen',ec='darkgreen',hatch='++',alpha=0.5,label='4')
plt.xlabel('x',fontsize=fs)
plt.ylabel('y',fontsize=fs)
ax.tick_params(axis='both', which='major', width=1.5, length=5, direction='in', pad=15)
ax.tick_params(axis='both', which='minor', width=1., length=3.5, direction='in', pad=15)
handles, labels= ax.get_legend_handles_labels()
handles[0], handles[1], handles[2], handles[3], handles[4] = handles[1], handles[2],handles[3], handles[4],handles[0]
labels[0], labels[1], labels[2], labels[3], labels[4] = labels[1], labels[2], labels[3], labels[4], labels[0]
ax.legend(handles,labels,loc='upper left',fontsize=15)
ax.yaxis.set_minor_locator(MultipleLocator(1))
ax.yaxis.set_major_locator(MultipleLocator(5))
tmp = list(ax.get_yticklabels())
ax.set_yticklabels(['' for _ in tmp])
ax.xaxis.set_minor_locator(MultipleLocator(1))
ax.xaxis.set_major_locator(MultipleLocator(5))
plt.xlim(10,0)
plt.tick_params(labelsize=ls)
plt.tight_layout()
plt.savefig('Correct_colors.png')
plt.savefig('Incorrect_colors.pdf')
Any help is highly appreciated.

Pyplot saving blank figures

I need to save graphics in very high quality, like eps. Basically I need to save 4 images of a hyperspectral data. Showing the graphics is not a problem, so I know my figures are ok, but I can't save them.
I have already tried other formats, like jpg,png or pdf, and none of them worked. I also already tried to save 4 figures instead of one figure with 4 subplots, but the problem persisted. I changed also matplotlib's backend a lot of times, and none of them worked.
Here is my code:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
RGB = np.random.randint(255, size=(3518,117,3))
var = RGB[:,:,0]
cmap = plt.cm.get_cmap('cividis')
col = 3
forma = "eps"
fig, ax = plt.subplots(1,col,figsize = (1.5,45))
plt.subplots_adjust(left = 2, right = 4)
im = ax[0].imshow(RGB.astype(np.uint8), cmap = cmap)
ax[1].pcolormesh(var, cmap = cmap)
ax[2].plot(np.mean(var,axis = 1),np.arange(var.shape[0]))
plt.colorbar(im)
fig.savefig("runnable" + "." + forma, format = forma,dpi=1200 )
plt.show()
I get a warning that I don't understand:
RunTimeWarning:"Mean of empty slice"
I've done some research and it seems like this is common when there is NaN in the data. However, I looked for it and didn't find any.
edit: I changed the code so it can be runnable.

Create scatter plot with data from multiple txt files

I'm trying to create scatter plot from several txt files. All files have the same structure: two columns with data and 'comma' as a separator:
54.1,12
65.7,11
122.2,18
etc
For small number of files i have this code:
import numpy as np
import matplotlib.pyplot as plt
import csv
# Create data
g1=np.loadtxt('214.txt',delimiter=',', unpack=True)
g2=np.loadtxt('228.txt',delimiter=',', unpack=True)
g3=np.loadtxt('491.txt',delimiter=',', unpack=True)
g4=np.loadtxt('647.txt',delimiter=',', unpack=True)
data = (g1, g2, g3,g4)
colors = ("red", "green", "blue", "black")
groups = ("214", "228", "491", "647")
# Create plot
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
for data, color, group in zip(data, colors, groups):
y, x = data
ax.scatter(x, y, alpha=0.8, c=color, edgecolors='none', s=30, label=group)
#Plot settings
plt.title('Matplot scatter plot')
plt.legend(loc=4)
axes = plt.gca()
axes.set_xlim([2,30])
axes.set_ylim([0,3000])
plt.gca().invert_yaxis()
plt.show()
Please advise how to modify it to read multiple (up to 50 - 100) txt files in folder, if number of them is different every time ?
I would search for all files in your current directory and identify which you want to extract data from. This can be done with something like:
from os import listdir, path
files = [f for f in listdir('.') if path.isfile(f)]
file_names = [file for file in files if file.startswith('file_name_identifer')]
This will give you a list of file names which contain the data you're wanting to extract, you can then just load them one by one in a for loop. Using similar loading techniques to what you've used above:
data = []
for file in file_names:
data.append(np.loadtxt('file', delimiter=',', unpack=True))
You could flatten this to a generator expression too:
data = [np.loadtxt('file', delimiter=',', unpack=True) for file in file_names]
If your files don't start with something which can be used to identify them, you can simply check some other way instead (change if file.startswith('file_name_indentifer') to something else which maybe checks if they're .txt files for instance: if file.endswith('.txt')).
You can get a list of all files in directory using method described in this post
And then do something like this:
data = []
for file in filenames:
data.append(np.loadtxt(file, delimiter=‘,’, unpack = True
#And do everything else you did with data
Though if your dataset is larger then available space in system memory I would consider adding datapoints to plot as you read the files
data = []
colors = [“red”,”green”,”blue”,”balck”]
for i, file in enumerate(filenames):
data = np.loadtxt(file, delimiter=‘,’,unpack=True)
group = file.split(‘.’)[0]
color = colors[i%len(colors)]
ax.scatter(data[0], data[1], alpha=0.8, c=color, edgecolors=‘none’, s=30, label=group)
P.S. quotes are typed wrong (both double and single ones) as I’m writing from a mobile device
Thanks for help. Here is what worked for me:
import numpy as np
import matplotlib.pyplot as plt
from os import listdir, path
import logging, sys
import random
data = []
#Get files with extension ".txt")
files = [f for f in listdir('.') if path.isfile(f)]
file_names = [file for file in files if file.endswith('.txt')]
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
# Create plot
for file in file_names:
data=np.loadtxt(file, delimiter=",", unpack = True)
color = ["#"+''.join([random.choice('0123456789ABCDEF')for j in range(6)])]
ax.scatter(data[1], data[0], alpha=0.8, c=color, edgecolors="none", s=30, label=file)
#Plot settings
plt.title('Matplot scatter plot')
plt.legend(loc=4)
axes = plt.gca()
plt.gca().invert_yaxis()
plt.show()

Matplotlib: Printing plot to pdf file : not working with figure()

I am trying plotting multiple pandas data frames to a single pdf file by:
def plot_user_data(df):
fig = plt.figure()
df.plot(x = 'm_srcaddr')
plt.xticks(df.index, df['m_srcaddr'], rotation=90)
fig.suptitle('User Data Usage for ')
return fig
for multiple df I am calling ::
plot = plot_user_data(df)
pdf = PdfPages('foo.pdf')
pdf.savefig()
Above code is creating a pdf file without plot and per page title only.
How ever if I change the function like:
def plot_user_data(df):
fig = df.plot(x = 'm_srcaddr').get_figure()
plt.xticks(df.index, df['m_srcaddr'], rotation=90)
fig.suptitle('User Data Usage for' )
return fig
I am not able to figure out why first function is not plotting actual plot.? Now I want to change the size of each figures as I am not aware how to change fig size in second function.

How to plot data from multiple two column text files with legends in Matplotlib?

How do I open multiple text files from different directories and plot them on a single graph with legends?
This is relatively simple if you use pylab (included with matplotlib) instead of matplotlib directly. Start off with a list of filenames and legend names, like [ ('name of file 1', 'label 1'), ('name of file 2', 'label 2'), ...]. Then you can use something like the following:
import pylab
datalist = [ ( pylab.loadtxt(filename), label ) for filename, label in list_of_files ]
for data, label in datalist:
pylab.plot( data[:,0], data[:,1], label=label )
pylab.legend()
pylab.title("Title of Plot")
pylab.xlabel("X Axis Label")
pylab.ylabel("Y Axis Label")
You also might want to add something like fmt='o' to the plot command, in order to change from a line to points. By default, matplotlib with pylab plots onto the same figure without clearing it, so you can just run the plot command multiple times.
Assume your file looks like this and is named test.txt (space delimited):
1 2
3 4
5 6
7 8
Then:
#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt
with open("test.txt") as f:
data = f.read()
data = data.split('\n')
x = [row.split(' ')[0] for row in data]
y = [row.split(' ')[1] for row in data]
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.set_title("Plot title...")
ax1.set_xlabel('your x label..')
ax1.set_ylabel('your y label...')
ax1.plot(x,y, c='r', label='the data')
leg = ax1.legend()
plt.show()
I find that browsing the gallery of plots on the matplotlib site helpful for figuring out legends and axes labels.
I feel the simplest way would be
from matplotlib import pyplot;
from pylab import genfromtxt;
mat0 = genfromtxt("data0.txt");
mat1 = genfromtxt("data1.txt");
pyplot.plot(mat0[:,0], mat0[:,1], label = "data0");
pyplot.plot(mat1[:,0], mat1[:,1], label = "data1");
pyplot.legend();
pyplot.show();
label is the string that is displayed on the legend
you can plot as many series of data points as possible before show() to plot all of them on the same graph
This is the simple way to plot simple graphs. For other options in genfromtxt go to this url.

Categories