Reduce left and right margins in matplotlib plot
One way to automatically do this is the bbox_inches='tight'
kwarg to plt.savefig
.
E.g.
import matplotlib.pyplot as plt
import numpy as np
data = np.arange(3000).reshape((100,30))
plt.imshow(data)
plt.savefig('test.png', bbox_inches='tight')
Another way is to use fig.tight_layout()
import matplotlib.pyplot as plt
import numpy as np
xs = np.linspace(0, 1, 20); ys = np.sin(xs)
fig = plt.figure()
axes = fig.add_subplot(1,1,1)
axes.plot(xs, ys)
# This should be called after all axes have been added
fig.tight_layout()
fig.savefig('test.png')
Matplotlib: Set different margins for left and right side
There is an old feature request for this, which is still open. So, no, you cannot set the margins independently as of any current version of matplotlib.
Of course you may write your own function to do what you want.
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
ax.plot([1,2,3],[1,3,1])
def set_xmargin(ax, left=0.0, right=0.3):
ax.set_xmargin(0)
ax.autoscale_view()
lim = ax.get_xlim()
delta = np.diff(lim)
left = lim[0] - delta*left
right = lim[1] + delta*right
ax.set_xlim(left,right)
set_xmargin(ax, left=0.05, right=0.2)
plt.show()
Using this in an animation would require to call it in each animation step. This may slow down the animation a bit, but should still be fine for most applications.
How to set the margins for a matplotlib figure?
Have a look at plt.tight_layout()
or plt.subplots_adjust()
or fig.savefig(bbox_inches='tight')
.
With subplots_adjust
you can adjust most parameters, while tight_layout()
and bbox_inches='tight'
are more or less semi automatic.
How do I extend the margin at the bottom of a figure in Matplotlib?
Two retroactive ways:
fig, ax = plt.subplots()
# ...
fig.tight_layout()
Or
fig.subplots_adjust(bottom=0.2) # or whatever
Here's a subplots_adjust
example: http://matplotlib.org/examples/pylab_examples/subplots_adjust.html
(but I prefer tight_layout
)
Removing white space around a saved image
I cannot claim I know exactly why or how my “solution” works, but this is what I had to do when I wanted to plot the outline of a couple of aerofoil sections — without white margins — to a PDF file.
(Note that I used matplotlib inside an IPython notebook, with the -pylab flag.)
plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0,
hspace = 0, wspace = 0)
plt.margins(0,0)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.savefig("filename.pdf", bbox_inches = 'tight',
pad_inches = 0)
I have tried to deactivate different parts of this, but this always lead to a white margin somewhere. You may even have modify this to keep fat lines near the limits of the figure from being shaved by the lack of margins.
How to remove inner margins from Matplotlib plots?
I think what you want to get might be obtained using the xlim and ylim methods inside your plotAudio
function. Since I don't have your data set, I will show you its application in a hypothetical noisy function example:
import numpy as np
import matplotlib.pyplot as plt
num = np.random.uniform(-np.pi, np.pi, 10000)
sig = np.sin(num) + np.random.normal(0, 1, 10000)
figure = plt.Figure(tight_layout=True)
plot = figure.add_subplot(111, position=[0, 0, 1, 1])
plot.axis("off")
plot.use_sticky_edges = True
plot.set_title(None)
plot.set_xlabel(None)
plot.set_ylabel(None)
plot.margins(0)
figure.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
figure.tight_layout(pad=0)
plt.xlim([-np.pi, np.pi])
plt.ylim([sig.min(), sig.max()])
plt.scatter(num, sig)
plt.show()
Here I include the plots with and without the explicit limits (basically commenting out the lines I added to your matplotlib code):
I hope this gives you some hints.
Edit:
After debugging your code with the supplied input file, I found that something very close to the desired output can be found by modifying the MatplotlibWidget
class like this:
class MatplotlibWidget(FigureCanvas):
def __init__(self, parent=None):
super(MatplotlibWidget, self).__init__(Figure())
self.setParent(parent)
self.figure = Figure(constrained_layout=True)
self.figure.set_facecolor("black")
self.canvas = FigureCanvas(self.figure)
mpl.rcParams["lines.linewidth"] = 1
mpl.rcParams["lines.color"] = "b"
def plotAudio(self, waveformData):
plot = self.figure.add_subplot(111)
plot.margins(0)
plot.axis("off")
plot.plot(waveformData)
By setting the constrained_layout
keyword argument one can obtain the following plot:
Changing values displayed in top right corner of matplotlib figure
You have to retrieve the x-value and use it as the index of your sound data list. As you have to check for the validity of the index, we define now a function NavigCoordin()
:
import numpy as np
from matplotlib import pyplot as plt
import soundfile as sf
data_mono = []
x_click = 0
# Loding an audio signal
data, sps = sf.read("test.wav")
# Signal loaded by sf.read() is stereo (after plotting there are going to be
# 2 values for every sample) so we need to make it mono. This is what a loop
# down below is doing.
for i in range(0,len(data)):
bufor = ((data[i][0] + data[i][1])/2)
data_mono.append(bufor)
fig, ax = plt.subplots(figsize=(15, 4))
#don't overwrite your axis object - you need it later on
ax.plot(data_mono)
#the function to determine the x-index and the corresponding y-value from the array
#and return a string depending on the x-value
def NavigCoordin(x, y):
if x>=0 and x<=len(data_mono):
return f"x: {int(x+0.5)}, y: {data_mono[int(x+0.5)]:.4f}"
else:
return "outside the range"
#link the function to the axis object
ax.format_coord = NavigCoordin
# Below function is creating a vertical line in a place of left mouse click.
# Right click is deleting recently created line.
def click(event):
global x_click
x_click = event.xdata
if event.button == plt.MouseButton.LEFT:
global line
line = ax.axvline(event.xdata)
elif event.button == plt.MouseButton.RIGHT:
ax.lines[-1].remove()
# "Connecting" the cursor to above function.
cid = fig.canvas.mpl_connect('button_press_event', click)
# Loop displaying the plot and refreshing it every 0.05 second. When x coordinate
# of registered click is bigger than 0.9999 of the maximal x value loop
# will be break.
while True:
plt.pause(0.05)
if x_click >= (len(data_mono))*0.9999:
break
Sample output:
Related Topics
Deleting Multiple Columns Based on Column Names in Pandas
Running an Interactive Command from Within Python
How to Initialize Weights in Pytorch
Display the Output of the Program on Gui with Tkinter
Except-Clause Deletes Local Variable
How to Convert 24 Hour Time to 12 Hour Time
Access to Table Objects on Webpage Using Python Selenium
Python Datetime to String Without Microsecond Component
How Are Python In-Place Operator Functions Different Than the Standard Operator Functions
Overloaded Functions in Python
Sql-Like Window Functions in Pandas: Row Numbering in Python Pandas Dataframe
Checking File Permissions in Linux with Python
How to Install Pip3 on Windows
Securely Storing Environment Variables in Gae with App.Yaml
Unicodedecodeerror: 'Ascii' Codec Can't Decode Byte 0Xe2 in Position 13: Ordinal Not in Range(128)