Extend python plots to full screen - python

I want to extent the python plots I am plotting using mpld3 to full screen. I wish to use mpld3 due to the following reasons
I wish to have around 4 plots and have the zoom option for each plot.
All plots must be displayed in the same window.
Here, I tried using tight_layout option to extend the plots to occupy full screen but it does not work as shown in the link at the end.I guess tight_layout does not work with mpld3. Is there any other way to make it stretch to full screen?
Also,how do I add text to the screen where am plotting? Like the 4 plots occupying 90% of the screen from top to bottom and the text occupying remaining 10% at the bottom?
import matplotlib.pyplot as plt
import mpld3
x = [1,2,3]
y = [1,4,9]
fig = plt.figure()
ax = fig.add_subplot(411)
ax.plot(x,y)
ax = fig.add_subplot(412)
ax.plot(x,y)
ax = fig.add_subplot(413)
ax.plot(x,y)
ax = fig.add_subplot(414)
ax.plot(x,y)
fig.tight_layout()
mpld3.show()
Check this link for output of the code http://i.stack.imgur.com/4mBRI.png

I think the size is defined by matplotlib, this means that adjusting this would result in a fullscreen plot.
From this topic: How to maximize a plt.show() window using Python
mng = plt.get_current_fig_manager()
mng.frame.Maximize(True)
Something like this might work.

fig.set_size_inches(x_val,y_val)
helped me resize the plot to fit the screen

Use window.state option to get a zoomed version:
plt.get_current_fig_manager().window.state('zoomed')

Related

How can I save a Matplotlib figure after changing the background color?

Using the Spyder IDE, I have created a matplotlib plot and changed the face (background) color of both the figure object and the axes object to black. When I try to save the figure using plt.savefig(...) the axes, title, and axes label are not included.
I have tried implementing the standard advice of adding bbox_inches='tight' to the plt.savefig() function for when the axes are cut off:
plt.savefig("my_fig_name.png", bbox_inches='tight')
To no avail. Others suggested that I change the plotting method to "inline" from "automatic" within either Jupyter Notebook or Spyder. This had no effect. I also tried to make sure there was enough room in the figure for my axes using:
fig.add_axes([0.1,0.1,0.75,0.75])
This does not work either. Below is enough to reproduce my experience.
import matplotlib.pyplot as plt
xs, ys = [0,1], [0,1]
fig = plt.figure(figsize=(6, 6)) # Adding tight_layout=True has no effect
ax = fig.add_subplot(1, 1, 1)
# When the following block is commented out, the color of the
# plot is unchanged and the plt.savefig function works perfectly
fig.patch.set_facecolor("#121111")
ax.set_facecolor("#121111")
ax.spines['top'].set_color("#121111")
ax.spines['right'].set_color("#121111")
ax.spines['bottom'].set_color('white')
ax.spines['left'].set_color('white')
ax.xaxis.label.set_color('white')
ax.tick_params(axis='x', colors='white')
ax.yaxis.label.set_color('white')
ax.tick_params(axis='y', colors='white')
ax.set_title("My Graph's Title", color="white")
plt.plot(xs, ys)
plt.xlabel("x-label")
plt.ylabel("y-label")
plt.savefig("my_fig_name.png", bbox_inches="tight")
I am expecting to get an image like this:
What I Expect to Get
However, plt.savefig(...) gives me the following result:
What I Actually Get
Curiously, there seems to be white space around the plot which does not disappear even when I add the tight_layout=True parameter to the matplotlib figure constructor.
fig = plt.figure(figsize=(6, 6), tight_layout=True)
And, when I comment out the code which changes the face color of the plot, the figure is saved correctly with all the axes and labels displayed correctly.
In order to solve your problem, you just have to specify the facecolor keyword argument to your plt.savefig call, in this case :
plt.savefig("my_fig_name.png", bbox_inches="tight", facecolor="#121111")
which gives the intended .png output :
For more information, see plt.savefig documentation.

plt.show() does nothing when used for the second time

I am just starting to learn data science using python on Data Camp and I noticed something while using the functions in matplotlib.pyplot
import matplotlib.pyplot as plt
year = [1500, 1600, 1700, 1800, 1900, 2000]
pop = [458, 580, 682, 1000, 1650, 6,127]
plt.plot(year, pop)
plt.show() # Here a window opens up and shows the figure for the first time
but when I try to show it again it doesn't..
plt.show() # for the second time.. nothing happens
And I have to retype the line above the show() to be able to show a figure again
Is this the normal thing or a problem?
Note: I am using the REPL
Answer
Yes, this is normal expected behavior for matplotlib figures.
Explanation
When you run plt.plot(...) you create on the one hand the lines instance of the actual plot:
>>> print( plt.plot(year, pop) )
[<matplotlib.lines.Line2D object at 0x000000000D8FDB00>]
...and on the other hand a Figure instance, which is set as the 'current figure' and accessible through plt.gcf() (short for "get current figure"):
>>> print( plt.gcf() )
Figure(432x288)
The lines (as well as other plot elements you might add) are all placed in the current figure. When plt.show() is called, the current figure is displayed and then emptied (!), which is why a second call of plt.show() doesn't plot anything.
Standard Workaround
One way of solving this is to explicitly keep hold of the current Figure instance and then show it directly with fig.show(), like this:
plt.plot(year, pop)
fig = plt.gcf() # Grabs the current figure
plt.show() # Shows plot
plt.show() # Does nothing
fig.show() # Shows plot again
fig.show() # Shows plot again...
A more commonly used alternative is to initialize the current figure explicitly in the beginning, prior to any plotting commands.
fig = plt.figure() # Initializes current figure
plt.plot(year, pop) # Adds to current figure
plt.show() # Shows plot
fig.show() # Shows plot again
This is often combined with the specification of some additional parameters for the figure, for example:
fig = plt.figure(figsize=(8,8))
For Jupyter Notebook Users
The fig.show() approach may not work in the context of Jupyter Notebooks and may instead produce the following warning and not show the plot:
C:\redacted\path\lib\site-packages\matplotlib\figure.py:459:
UserWarning: matplotlib is currently using a non-GUI backend, so
cannot show the figure
Fortunately, simply writing fig at the end of a code cell (instead of fig.show()) will push the figure to the cell's output and display it anyway. If you need to display it multiple times from within the same code cell, you can achieve the same effect using the display function:
fig = plt.figure() # Initializes current figure
plt.plot(year, pop) # Adds to current figure
plt.show() # Shows plot
plt.show() # Does nothing
from IPython.display import display
display(fig) # Shows plot again
display(fig) # Shows plot again...
Making Use of Functions
One reason for wanting to show a figure multiple times is to make a variety of different modifications each time. This can be done using the fig approach discussed above but for more extensive plot definitions it is often easier to simply wrap the base figure in a function and call it repeatedly.
Example:
def my_plot(year, pop):
plt.plot(year, pop)
plt.xlabel("year")
plt.ylabel("population")
my_plot(year, pop)
plt.show() # Shows plot
my_plot(year, pop)
plt.show() # Shows plot again
my_plot(year, pop)
plt.title("demographics plot")
plt.show() # Shows plot again, this time with title
Using command:
%matplotlib
in ipython3 help me to use separate window with plot
Start ipython3 and issue the commands:
import matplotlib.pyplot as plt
%matplotlib #plot in separate window
fig, ax = plt.subplots() #Appear empty Tcl window for image
ax.plot([1, 2, 3, 4], [5, 6, 7, 8]) #Appear graph in window
In some version of matplotlib, fig.show() does not block the window for showing plot multiple times. so, Quick fixes using self.fig.waitforbuttonpress() it waits user to press the button for next plot visualisation.
self.fig.show()
plt.pause(0.1)
self.fig.waitforbuttonpress()

Incomple text while saving seaborn figures [duplicate]

Updated MRE with subplots
I'm not sure of the usefulness of the original question and MRE. The margin padding seems to be properly adjusted for large x and y labels.
The issue is reproducible with subplots.
Using matplotlib 3.4.2
fig, axes = plt.subplots(ncols=2, nrows=2, figsize=(8, 6))
axes = axes.flatten()
for ax in axes:
ax.set_ylabel(r'$\ln\left(\frac{x_a-x_b}{x_a-x_c}\right)$')
ax.set_xlabel(r'$\ln\left(\frac{x_a-x_d}{x_a-x_e}\right)$')
plt.show()
Original
I am plotting a dataset using matplotlib where I have an xlabel that is quite "tall" (it's a formula rendered in TeX that contains a fraction and is therefore has the height equivalent of a couple of lines of text).
In any case, the bottom of the formula is always cut off when I draw the figures. Changing figure size doesn't seem to help this, and I haven't been able to figure out how to shift the x-axis "up" to make room for the xlabel. Something like that would be a reasonable temporary solution, but what would be nice would be to have a way to make matplotlib recognize automatically that the label is cut off and resize accordingly.
Here's an example of what I mean:
import matplotlib.pyplot as plt
plt.figure()
plt.ylabel(r'$\ln\left(\frac{x_a-x_b}{x_a-x_c}\right)$')
plt.xlabel(r'$\ln\left(\frac{x_a-x_d}{x_a-x_e}\right)$', fontsize=50)
plt.title('Example with matplotlib 3.4.2\nMRE no longer an issue')
plt.show()
The entire ylabel is visible, however, the xlabel is cut off at the bottom.
In the case this is a machine-specific problem, I am running this on OSX 10.6.8 with matplotlib 1.0.0
Use:
import matplotlib.pyplot as plt
plt.gcf().subplots_adjust(bottom=0.15)
# alternate option without .gcf
plt.subplots_adjust(bottom=0.15)
to make room for the label, where plt.gcf() means get the current figure. plt.gca(), which gets the current Axes, can also be used.
Edit:
Since I gave the answer, matplotlib has added the plt.tight_layout() function.
See matplotlib Tutorials: Tight Layout Guide
So I suggest using it:
fig, axes = plt.subplots(ncols=2, nrows=2, figsize=(8, 6))
axes = axes.flatten()
for ax in axes:
ax.set_ylabel(r'$\ln\left(\frac{x_a-x_b}{x_a-x_c}\right)$')
ax.set_xlabel(r'$\ln\left(\frac{x_a-x_d}{x_a-x_e}\right)$')
plt.tight_layout()
plt.show()
In case you want to store it to a file, you solve it using bbox_inches="tight" argument:
plt.savefig('myfile.png', bbox_inches="tight")
An easy option is to configure matplotlib to automatically adjust the plot size. It works perfectly for me and I'm not sure why it's not activated by default.
Method 1
Set this in your matplotlibrc file
figure.autolayout : True
See here for more information on customizing the matplotlibrc file: http://matplotlib.org/users/customizing.html
Method 2
Update the rcParams during runtime like this
from matplotlib import rcParams
rcParams.update({'figure.autolayout': True})
The advantage of using this approach is that your code will produce the same graphs on differently-configured machines.
plt.autoscale() worked for me.
You can also set custom padding as defaults in your $HOME/.matplotlib/matplotlib_rc as follows. In the example below I have modified both the bottom and left out-of-the-box padding:
# The figure subplot parameters. All dimensions are a fraction of the
# figure width or height
figure.subplot.left : 0.1 #left side of the subplots of the figure
#figure.subplot.right : 0.9
figure.subplot.bottom : 0.15
...
There is also a way to do this using the OOP interface, applying tight_layout directly to a figure:
fig, ax = plt.subplots()
fig.set_tight_layout(True)
https://matplotlib.org/stable/api/figure_api.html
for some reason sharex was set to True so I turned it back to False and it worked fine.
df.plot(........,sharex=False)
You need to use sizzors to modify the axis-range:
import sizzors as sizzors_module
sizzors_module.reshape_the_axis(plt).save("literlymylief.tiff")

Save an image (only content, without axes or anything else) to a file using Matloptlib

I'd like to obtain a spectrogram out of a wav file and then save it to a png, but I need just the content of the image (not axes or anything else). I came across these questions
Matplotlib plots: removing axis, legends and white spaces
scipy: savefig without frames, axes, only content
I've also read the Matplotlib documentation but it seems useless and so either answers to questions above are outdated or I'm doing something wrong because simple
plt.savefig('out.png', bbox_inches='tight', pad_inches=0)
does not do what I want to achieve. Initially I tried to follow this guide but the code crashes. Then I tried this approach, but since it's outdated I modified it a little:
import matplotlib.pyplot as plt
from scipy.io import wavfile
import numpy as np
def graph_spectrogram(wav_file):
rate, data = wavfile.read(wav_file)
pxx, freqs, bins, im = plt.specgram(x=data, Fs=rate, noverlap=384, NFFT=512)
plt.axis('off')
plt.savefig('sp_xyz.png', bbox_inches='tight', dpi=300, frameon='false')
if __name__ == '__main__': # Main function
graph_spectrogram('...')
This is what I got:
Maybe it's not visible, but there's a white border around the content (from the biggest to the smallest): left, bottom, top, right. I want the same image but just the content without anything else. How can I achieve that? I use python 3.6 and Matplotlib 2.0.2.
I think you want subplots_adjust:
fig,ax = plt.subplots(1)
fig.subplots_adjust(left=0,right=1,bottom=0,top=1)
ax.axis('tight')
ax.axis('off')
In this case:
import matplotlib.pyplot as plt
from scipy.io import wavfile
import numpy as np
def graph_spectrogram(wav_file):
rate, data = wavfile.read(wav_file)
fig,ax = plt.subplots(1)
fig.subplots_adjust(left=0,right=1,bottom=0,top=1)
ax.axis('off')
pxx, freqs, bins, im = ax.specgram(x=data, Fs=rate, noverlap=384, NFFT=512)
ax.axis('off')
fig.savefig('sp_xyz.png', dpi=300, frameon='false')
if __name__ == '__main__': # Main function
graph_spectrogram('...')
May be helpful for someone who use librosa latest versions.
You can add transparent=True to the plt.savefig() function to set transparent background. But the problem is still x and y axis information are visible. Hens, you need to remove axis details using ax.set_axis_off()
You can remove right side color-bar by commenting out plt.colorbar()
plt.figure(figsize=(12, 4))
ax = plt.axes()
ax.set_axis_off()
plt.set_cmap('hot')
librosa.display.specshow(librosa.amplitude_to_db(S_full[:, idx], ref=np.max), y_axis='log', x_axis='time',sr=sr)
plt.colorbar()
plt.savefig(f'{args["output"]}/{name}_{i}.png', bbox_inches='tight', transparent=True, pad_inches=0.0 )
Please click images to check differences
When nothing is changed(Default)
When the axis informations are off Using ax.set_axis_off()
Here, this image doesn't have axis info but white background is there.
When enabling transparent using transparent= True
Here, this image doesn't have white background but axis info is there.
With axis info are off and enabling transparent
This image doesn't have either white background or axis info
You may not see the exact differences since images might be changed when uploading.

Second y-axis label getting cut off

I'm trying to plot two sets of data in a bar graph with matplotlib, so I'm using two axes with the twinx() method. However, the second y-axis label gets cut off. I've tried a few different methods with no success (tight_layout(), setting the major_pads in rcParams, etc...). I feel like the solution is simple, but I haven't come across it yet.
Here's a MWE:
#!/usr/bin/env python
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
matplotlib.rcParams.update({'font.size': 21})
ax = plt.gca()
plt.ylabel('Data1') #Left side
ax2 = ax.twinx()
for i in range(10):
if(i%2==0):
ax.bar(i,np.random.randint(10))
else:
ax2.bar(i,np.random.randint(1000),color='k')
plt.ylabel('Data2') #Right
side
plt.savefig("test.png")
I just figured it out: the trick is to use bbox_inches='tight' in savefig.
E.G. plt.savefig("test.png",bbox_inches='tight')
I encountered the same issue which plt.tight_layout() did not automatically solve.
Instead, I used the labelpad argument in ylabel/set_ylabel as such:
ax.set_ylabel('label here', rotation=270, color='k', labelpad=15)
I guess this was not implemented when you asked this question, but as it's the top result on google, hopefully it can help users of the current matplotlib version.

Categories

Resources