Stacking multiple plots on a 2Y axis - matplotlib

I am trying to plot multiple plots in a 2Y plot.
I have the following code:
Has a list of files to get some data;
Gets the x and y components of data to plot in y-axis 1 and y-axis 2;
Plots data.
When the loop iterates, it plots on different figures. I would like to get all the plots in the same figure.
Can anyone give me some help on this?
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
file=[list of paths]
for i in files:
# Loads Data from an excel file
data = pd.read_excel(files[i],sheet_name='Results',dtype=float)
# Gets x and y data from the loaded files
x=data.iloc[:,-3]
y1=data.iloc[:,-2]
y12=data.iloc[:,-1]
y2=data.iloc[:,3]
fig1=plt.figure()
ax1 = fig1.add_subplot(111)
ax1.set_xlabel=('x')
ax1.set_ylabel=('y')
ax1.plot(x,y1)
ax1.semilogy(x,y12)
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
ax2.plot(x,y2)
fig1.tight_layout()
plt.show()

You should instantiate the figure outside the loop, and then add the subplots while iterating. In this way you will have a single figure and all the plots inside it.
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
files=[list of paths]
fig1=plt.figure()
for i in files:
# Loads Data from an excel file
data = pd.read_excel(files[i],sheet_name='Results',dtype=float)
# Gets x and y data from the loaded files
x=data.iloc[:,-3]
y1=data.iloc[:,-2]
y12=data.iloc[:,-1]
y2=data.iloc[:,3]
ax1 = fig1.add_subplot(111)
ax1.set_xlabel=('x')
ax1.set_ylabel=('y')
ax1.plot(x,y1)
ax1.semilogy(x,y12)
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
ax2.plot(x,y2)
fig1.tight_layout()
plt.show()

Related

Data visualization using Matplotlib

By using this code I'm able to generate 20 data points on y-axis corresponding to x-axis, but I want to mark the 25 data points on the line as downward pointed triangles without changing arr_x=np.linspace(0.0,5.0,20) to arr_x=np.linspace(0.0,5.0,25).
will it possible to mark additional data points on y-axis without changing x-axis ?
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
def multi_curve_plot():
# Write your functionality below
fig=plt.figure(figsize=(13,4))
ax=fig.add_subplot(111)
arr_x=np.linspace(0.0,5.0,20)
arr_y1=np.array(arr_x)
arr_y2=np.array(arr_x**2)
arr_y3=np.array(arr_x**3)
ax.set(title="Linear, Quadratic, & Cubic Equations", xlabel="arr_X",
ylabel="f(arr_X)")
ax.plot(arr_x, arr_y1, label="y = arr_x", color="green", marker="v")
ax.plot(arr_x, arr_y2, label ="y = arr_x**2", color ="blue", marker="s")
ax.plot(arr_x, arr_y3, label="y = arr_x**3", color="red", marker="o")
plt.legend()
return fig
return None
multi_curve_plot()
I tried changing arr_x=np.linspace(0.0,5.0,20) to arr_x=np.linspace(0.0,5.0,25). But I want to show 25 data points on y axis without changing x-axis attributes.

How to plot the sound wave, mfcc,and mel spectrogram on a single figure?

I have a folder containing multiple wav files (currently say 4). I want to plot the wav, its mfcc and mel spectrogram in a row , so finally a figure with 12 plots(each row with three figure, and hence four rows). I am not able to plot the graph, only extracted the features. Can some one help with this for loop please. I mean how to use subplot command and how to store each figure in loop.
Regards
path=glob.glob('the path having four wav files/*.wav')
for p in path:
y, sr = librosa.load(p, sr=16000)
mfcc=librosa.feature.mfcc(y)
S = librosa.feature.melspectrogram(y, sr)
fig, ax = plt.subplot(4,3,.....)
librosa.display.waveplot(y, sr=sr)
librosa.display.specshow(librosa.power_to_db(S, ref=np.max))
librosa.display.specshow(mfcc, x_axis="time",y_axis="mel")
plt.show()
import matplotlib.pyplot as plt
Arrays=np.random.rand(6,10,10)
N_figures=Arrays.shape[0]
for Id in range(1,N_figures+1):
Array=Arrays[Id-1]
plt.subplot(N_figures/2,N_figures/3,Id)
plt.imshow(Array)
You just need to change imshow with desired plottings. Since I don't have the spectrogram files I've used randomly created NumPy arrays. Your implementation doesn't work because fig, ax = plt.subplot(4,3,.....)
is not appropriate to use. Fig and axs returns in the function plt.subplots not plt.subplot.You can also use that method but outside of the for loop and then access the axs elements.
The final code is :
import matplotlib.pyplot as plt
import librosa
import librosa.display
import glob
path=glob.glob('E:/Python_On_All_Dataset/Four emotion_for plot/*.wav')
fig, ax = plt.subplots(nrows=4, ncols=3, sharex=True)
for i in range(4) :
y, sr = librosa.load(path[i], sr=16000)
librosa.display.waveplot(y, sr, ax=ax[i, 0]) # put wave in row i, column 0
plt.axis('off')
mfcc=librosa.feature.mfcc(y)
librosa.display.specshow(mfcc, x_axis='time', ax=ax[i, 1]) # mfcc in row i, column 1
S = librosa.feature.melspectrogram(y, sr)
librosa.display.specshow(librosa.power_to_db(S), x_axis='time', y_axis='log', ax=ax[i, 2]) # spectrogram in row i, column 2
Tried putting this axis(off after every plot, but somehow its not working)

Is there a way to draw shapes on a python pandas plot

I am creating shot plots for NHL games and I have succeeded in making the plot, but I would like to draw the lines that you see on a hockey rink on it. I basically just want to draw two circles and two lines on the plot like this.
Let me know if this is possible/how I could do it
Pandas plot is in fact matplotlib plot, you can assign it to variable and modify it according to your needs ( add horizontal and vertical lines or shapes, text, etc)
# plot your data, but instead diplaying it assing Figure and Axis to variables
fig, ax = df.plot()
ax.vlines(x, ymin, ymax, colors='k', linestyles='solid') # adjust to your needs
plt.show()
working code sample
import pandas as pd
import matplotlib.pyplot as plt
import seaborn
from matplotlib.patches import Circle
from matplotlib.collections import PatchCollection
df = seaborn.load_dataset('tips')
ax = df.plot.scatter(x='total_bill', y='tip')
ax.vlines(x=40, ymin=0, ymax=20, colors='red')
patches = [Circle((50,10), radius=3)]
collection = PatchCollection(patches, alpha=0.4)
ax.add_collection(collection)
plt.show()

How to plot (correctly) lineplot from pandas dataframe?

I'm plotting a lineplot from a pandas dataframe. However the labels are overlapped on the right side of the X axis instead of to the relative point mark on the line. What is missing?
Here the full code and the pic
#importing pandas package
import pandas as pd
import matplotlib.pyplot as plt
import csv
import seaborn as sns
# making data frame from csv file
dataset = pd.read_csv('curve.csv.csv')
df = pd.DataFrame(dataset.sort_values('Split')[['Split', 'Score']])
df.reset_index(drop=True, inplace=True)
print(df)
ax = df.plot.line(x='Split',y='Score',color='green',marker=".")
ax.set_xlim((0, 1))
ax.grid(True)
# set the tick marks for x axis
ax.set_xticks(df.Score)
ax.set_xticklabels(['.005','.010','.015','.020','.040','.060','.080','1','15','20','25','30','35','40','45','50','55','60'
,'65','70','75','80','85','90','95'])
ax.grid(True, linestyle='-.')
ax.tick_params(labelcolor='r', labelsize='medium', width=3)
plt.show()
My desired output would be to have all the labels on the X axis aligned to the relative marker point on the line.
You seem to be using the y-values (df.Score) as the positions of your x-ticks.
I assume you meant
ax.set_xticks(df['Split'])

changing the size of subplots with matplotlib

I am trying to plot multiple rgb images with matplotlib
the code I am using is:
import numpy as np
import matplotlib.pyplot as plt
for i in range(0, images):
test = np.random.rand(1080, 720,3)
plt.subplot(images,2,i+1)
plt.imshow(test, interpolation='none')
the subplots appear tiny though as thumbnails
How can I make them bigger?
I have seen solutions using
fig, ax = plt.subplots()
syntax before but not with plt.subplot ?
plt.subplots initiates a subplot grid, while plt.subplot adds a subplot. So the difference is whether you want to initiate you plot right away or fill it over time. Since it seems, that you know how many images to plot beforehand, I would also recommend going with subplots.
Also notice, that the way you use plt.subplot you generate empy subplots in between the ones you are actually using, which is another reason they are so small.
import numpy as np
import matplotlib.pyplot as plt
images = 4
fig, axes = plt.subplots(images, 1, # Puts subplots in the axes variable
figsize=(4, 10), # Use figsize to set the size of the whole plot
dpi=200, # Further refine size with dpi setting
tight_layout=True) # Makes enough room between plots for labels
for i, ax in enumerate(axes):
y = np.random.randn(512, 512)
ax.imshow(y)
ax.set_title(str(i), fontweight='bold')