Seaborn plot saved to eps does not show grid - python

I have played around a bit and can't get saving a plot rendered with seaborn correctly. When using plt.savefig I lose the grid. However, using plt.show and then saving the figure manually works. This happens with eps and png as well. I need to render large amount of plots so this is a problem.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style = 'darkgrid', font_scale=2)
t = np.arange(100)
y = np.random.rand(len(t))
plt.plot(t,y)
plt.title('Test title')
plt.xlabel('Test xlab')
plt.ylabel('Tex $y_i = w_i x_i$')
plt.tight_layout()
#plt.show()
plt.savefig('test_plot.eps', format='eps')
Automatic save
Manual save

The solution was I had "savefig.transparent : True" in my matplotlibrc that I for some reason needed before. Changing this to False solved the problem in my case.

Related

Rightmost part of axes disappears in Matplotlib PostScript figure

I'm creating a Matplotlib figure, which I need to be quite wide (174 mm) and in .eps format. I also need it to be created with LaTeX for consistency with other figures. The problem is that the rightmost parts of the axes do not appear in the output figure, and the legend's box and handles also disappear.
The problem appears only if the figure if very wide, when I use LaTeX to produce it, and when I save it in .eps. The figure is as expected if it is thinner, if I save it in .pdf or .png, or if I just replace plt.savefig(...) with plt.show() and use Matplotlib's default viewer.
To be clearer, consider the following code.
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = np.exp(x)
mpl.rcParams['text.usetex'] = True
mm = 1/25.4
fig = plt.figure(figsize=(174*mm, 44*mm))
plt.plot(x, y, label='exponential')
plt.legend(loc='lower right')
plt.tight_layout()
plt.savefig('test.eps')
This outputs the following figure, where the legend handle and the rightmost part of the axes do not appear.
If it can help, the .eps file output by the above code is available here.

Matplotlib animation on spyder python output a single image

I wanted to make an animation in spyder but i just get a static plot. this is the code.
import numpy as np
import matplotlib.pyplot as plt
plt.figure(1)
plt.clf()
plt.axis([-10,10,-10,10])
n=10
pos=(20*np.random.sample(n*2)-10).reshape(n,2)
vel=(0.3*np.random.normal(size=n*2)).reshape(n,2)
sizes=100*np.random.sample(n)+100
colors=np.random.sample([n,4]
circles=plt.scatter(pos[:,0], pos[:,1], marker='o', s=sizes, c=colors)
for i in range(100):
pos=pos+vel
bounce=abs(pos)>10
vel[bounce] = -vel[bounce]
circles.set_offsets(pos)
plt.draw()
plt.show()
this is what i get, I've tried with %matplotlib qt5 but it doesn't change the output and the stays still1]1
There are two things you need to do to make the animation work.
First, is that you need to show the figure once the animation made, so plt.show() should get out of the for loop.
Also to be able to see the frames, you need to put a small amount of time between them, which an be achieved by adding, for example, plt.pause(t) (t in seconds) in between the frames.
The code shown below is the edited code generating an animated plot.
import numpy as np
import matplotlib.pyplot as plt
plt.figure(1)
plt.clf()
plt.axis([-10,10,-10,10])
n=10
pos=(20*np.random.sample(n*2)-10).reshape(n,2)
vel=(0.3*np.random.normal(size=n*2)).reshape(n,2)
sizes=100*np.random.sample(n)+100
colors=np.random.sample([n,4])
circles=plt.scatter(pos[:,0], pos[:,1], marker='o', s=sizes, c=colors)
for i in range(100):
pos=pos+vel
bounce=abs(pos)>10
vel[bounce] = -vel[bounce]
circles.set_offsets(pos)
plt.draw()
plt.pause(0.05)
plt.show()

pyplot order of magnitude fontsize modification when using scientific ticks python [duplicate]

I am attempting to plot differential cross-sections of nuclear decays and so the magnitudes of the y-axis are around 10^-38 (m^2) pylab as default plots the axis as 0.0,0.2,0.4... etc and has a '1e-38' at the top of the y-axis.
I need to increase the font size of just this little bit, I have tried adjusting the label size
py.tick_params(axis='y', labelsize=20)
but this only adjusts the labels 0.0,0.2,0.4....
Many thanks for all help
You can access the text object using the ax.yaxis.get_offset_text().
import numpy as np
import matplotlib.pyplot as plt
# Generate some data
N = 10
x = np.arange(N)
y = np.array([i*(10**-38) for i in x])
fig, ax = plt.subplots()
# Plot the data
ax.plot(x,y)
# Get the text object
text = ax.yaxis.get_offset_text()
# Set the size.
text.set_size(30) # Overkill!
plt.show()
I've written the solution above using matplotlib.pyplot rather than pylab though if you absolutely have to use pylab then it can be changed (though I'd recommend you use matplotlib.pyplot in any case as they are pretty much identical you can just do a lot more with pyplot easier).
Edit
If you were to use pylab then the code would be:
pylab.plot(x, y)
ax = pylab.gca() # Gets the current axis object
text = ax.yaxis.get_offset_text() # Get the text object
text.set_size(30) # # Set the size.
pylab.show()
An example plot with an (overkill!) offset text.

ploting a bar plot for large amount of data

I have a 752 data points which i need to plot,
I have plotted the data on bar plot using seaborn library in python , but graph i get is very unclear and I am not able to analyze anything through graph , is there any way i can view this graph more clearly and all data points fit with labels seen clearly in python

code written is following
import seaborn as sns
sns.set_style("whitegrid")
ax = sns.barplot(x="Events", y = "Count" , data = Unique_Complaints)
It is always difficult to visualise so many points. Nihal, has rightly pointed that it is best to use Pandas and statistical analysis to extract information from your data. Having said this, IDEs like Spyder and Pycharm and packages like Bokeh allow interactive plots where you can zoom to different parts of the plot. Here is an example with Pycharm:
Code:
# Import libraries
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
# Exponential decay function
x = np.arange(1,10, 0.1)
A = 7000
y = A*np.exp(-x)
# Plot the exponential function
sns.barplot(x = x, y = y)
plt.show()
Figure without magnification
Magnified figure
To see a large amount of data you can use the figure from matplotlib.pyplot like this
from matplotlib.pyplot import figure
figure(num=None, figsize=(20,18), dpi=80, facecolor='w', edgecolor='r')
sns.barplot(x="Events", y = "Count" , data = Unique_Complaints)
plt.show()
I am using this to see a graph with 49 variables and the result is:
My code is
from matplotlib.pyplot import figure
figure(num=None, figsize=(20,18), dpi=256, facecolor='w', edgecolor='r')
plt.title("Missing Value Prercentage")
sns.barplot(miss_val_per, df.columns)
plt.show()
Data I am using is:
https://www.kaggle.com/sobhanmoosavi/us-accidents
just swap x and y and try to increase the fig size

Matplotlib crashes after saving many plots

I am plotting and saving thousands of files for later animation in a loop like so:
import matplotlib.pyplot as plt
for result in results:
plt.figure()
plt.plot(result) # this changes
plt.xlabel('xlabel') # this doesn't change
plt.ylabel('ylabel') # this doesn't change
plt.title('title') # this changes
plt.ylim([0,1]) # this doesn't change
plt.grid(True) # this doesn't change
plt.savefig(location, bbox_inches=0) # this changes
When I run this with a lot of results, it crashes after several thousand plots are saved. I think what I want to do is reuse my axes like in this answer: https://stackoverflow.com/a/11688881/354979 but I don't understand how. How can I optimize it?
I would create a single figure and clear the figure each time (use .clf).
import matplotlib.pyplot as plt
fig = plt.figure()
for result in results:
fig.clf() # Clears the current figure
...
You are running out of memory since each call to plt.figure creates a new figure object. Per #tcaswell's comment, I think this would be faster than .close. The differences are explained in:
When to use cla(), clf() or close() for clearing a plot in matplotlib?
Although this question is old, the answer would be:
import matplotlib.pyplot as plt
fig = plt.figure()
plot = plt.plot(results[0])
title = plt.title('title')
plt.xlabel('xlabel')
plt.ylabel('ylabel')
plt.ylim([0,1])
plt.grid(True)
for i in range(1,len(results)):
plot.set_data(results[i])
title.set_text('new title')
plt.savefig(location[i], bbox_inches=0)
plt.close('all')

Categories

Resources