You have defined figs with the px.bar() method.
Per documentation px.bar() returns a plotly.graph_objects.Figure object.
Looking at this plotly.graph_objects.Figure class' documentation we can see all the methods available on this plotly.graph_objects.Figure class.
show() appears to be a valid method for this type of object. However there is no savefig() method for this class.
This is why fig.show() works and fig.savefig() doesn't work.
It looks like there is a savefig() method on the matplotlib.pyplot class as documented here, however your figs object is an instance of plotly.graph_objects.Figure not matplotlib.pyplot.
If your goal is to write your figs object to a file, it looks like the documentation specifies 3 methods that provide this functionality:
plotly.graph_objects.Figure
- write_html
- write_image
- write_json
Try replacing:
figs.savefig('static/images/staff_plot.png')
with
figs.write_image(file='static/images/staff_plot.png', format='.png')
You have defined figs with the px.bar() method.
Per documentation px.bar() returns a plotly.graph_objects.Figure object.
Looking at this plotly.graph_objects.Figure class' documentation we can see all the methods available on this plotly.graph_objects.Figure class.
show() appears to be a valid method for this type of object. However there is no savefig() method for this class.
This is why fig.show() works and fig.savefig() doesn't work.
It looks like there is a savefig() method on the matplotlib.pyplot class as documented here, however your figs object is an instance of plotly.graph_objects.Figure not matplotlib.pyplot.
If your goal is to write your figs object to a file, it looks like the documentation specifies 3 methods that provide this functionality:
plotly.graph_objects.Figure
- write_html
- write_image
- write_json
Try replacing:
figs.savefig('static/images/staff_plot.png')
with
figs.write_image(file='static/images/staff_plot.png', format='.png')
Instead of using figs.savefig, try to use plt.savefig
import matplotlib.pyplot as plt
plt.savefig('static/images/staff_plot.png')
Having Problem of Pyplot Feature on Streamlit
Rendering Matplotlib AxesSubplots in Streamlit
'AxesImage' object has no attribute 'savefig'
Plotting from missing library results in: AttributeError: 'AxesSubplot' object has no attribute 'savefig'
I solved the issue by changing
ax.savefig('file.png')
to
ax.figure.savefig('file.png')
I guess accessing the figure directly is one way to get to the savefig() method for the barplot.
@WoodChopper also has a working solution, but it requires another import statement, and utilizing pyplot's savefig() directly.
Either solution does require setting matplotlib.use('Agg') to get around the DISPLAY variable error. As the referenced post noted, this has to be set before importing other matplotlib libraries.
I guess you should import pyplot.
import matplotlib.pyplot as plt
plt.savefig()
From the documentation for matplotlib.pyplot.hist:
The return value is a tuple (
n,bins,patches) or ([n0,n1, ...],bins, [patches0,patches1,...]) if the input contains multiple data.
From the documentation for matplotlib.pyplot.savefig:
Save the current figure.
It looks like you should call savefig in the same way you call hist, not on the result of the hist call.
plt.savefig("{}_temperature.png".format(filename), format='png')
...
I've adapted your code and took the liberty to change the several lines creating a figure by list in comprehension of for loops:
import matplotlib.pyplot as plt
# should be equal when using .pylab
import numpy.random as rnd
# generate_data
n_points = 1000
temperature_graph_array = rnd.random(n_points)
feelslike_graph_array = rnd.random(n_points)
windspeed_graph_array = rnd.random(n_points)
windgustspeed_graph_array = rnd.random(n_points)
pressure_graph_array = rnd.random(n_points)
humidity_graph_array = rnd.random(n_points)
list_of_data = [temperature_graph_array,
feelslike_graph_array,
windspeed_graph_array,
windgustspeed_graph_array,
pressure_graph_array,
humidity_graph_array]
list_of_names = ['temperature',
'feelslike',
'windspeed',
'windgustspeed',
'pressure',
'humidity']
# create the figures:
#figure1 = plt.figure()
#figure2 = plt.figure()
#figure3 = plt.figure()
#figure4 = plt.figure()
#figure5 = plt.figure()
#figure6 = plt.figure()
#list_of_figs = [figure1, figure2, figure3, figure4, figure5, figure6]
## could be:
list_of_figs = [plt.figure() for i in range(6)]
# create the axis:
#ax1 = figure1.add_subplot(111)
#ax2 = figure2.add_subplot(111)
#ax3 = figure3.add_subplot(111)
#ax4 = figure4.add_subplot(111)
#ax5 = figure5.add_subplot(111)
#ax6 = figure6.add_subplot(111)
#list_of_axis = [ax1, ax2, ax3, ax4, ax5, ax6]
## could be:
list_of_axis = [fig.add_subplot(111) for fig in list_of_figs]
# plot the histograms
# notice `plt.hist` returns a tuple (n, bins, patches) or
# ([n0, n1, ...], bins, [patches0, patches1,...]) if the input
# contains multiple data
#hist1 = ax1.hist(temperature_graph_array, color="blue")
#hist2 = ax2.hist(feelslike_graph_array, color="blue")
#hist3 = ax3.hist(windspeed_graph_array, color="blue")
#hist4 = ax4.hist(windgustspeed_graph_array, color="blue")
#hist5 = ax5.hist(pressure_graph_array, color="blue")
#hist6 = ax6.hist(humidity_graph_array, color="blue")
#list_of_hists = [hist1, hist2, hist3, hist4, hist5, hist6]
## could be:
list_of_hists = []
for i, ax in enumerate(list_of_axis):
list_of_hists.append(ax.hist(list_of_data[i], color="blue"))
filename = 'output_graph'
for i, fig in enumerate(list_of_figs):
name = list_of_names[i].capitalize()
list_of_axis[i].set_title(name)
fig.tight_layout()
fig.savefig("{}_{}.png".format(filename,name), format='png')
Will not post the resulting figures, but this gives me 6 little .png files in the same folder as the script.
Even better, you can use a function to do all that to your data:
def save_hist(data, name, filename):
fig = plt.figure()
ax = fig.add_subplot(111)
ax.hist(data, color="blue")
ax.set_title(name)
fig.tight_layout()
fig.savefig("{}_{}.png".format(filename,name), format='png')
plt.close(fig)
filename = 'output_graph_2'
for data, name in zip(list_of_data, list_of_names):
save_hist(data, name, filename)
The call to plt.savefig("figure.png") will only work if you have imported as follows:
import matplotlib.pyplot as plt.
I believe your error lies with plt and what it actually references. If you imported like this:import matplotlib as plt
then you would need to call the required function like this: plt.pyplot.savefig("figure.png")
If you imported like this:import matplotlib.pyplot as plt
then you can call the required function like this: plt.savefig("figure.png")
Thanks for including the error, but what that's saying is that matplotlib doesn't have a savefig() function.
I think it's matplotlib.pyplot.savefig() as per this link: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.savefig.html
Edit your code to say: plt.pyplot.savefig().
The gcf method is depricated in V 0.14, The below code works for me:
plot = dtf.plot()
fig = plot.get_figure()
fig.savefig("output.png")
You can use ax.figure.savefig(), as suggested in a comment on the question:
import pandas as pd
df = pd.DataFrame([0, 1])
ax = df.plot.line()
ax.figure.savefig('demo-file.pdf')
This has no practical benefit over ax.get_figure().savefig() as suggested in other answers, so you can pick the option you find the most aesthetically pleasing. In fact, get_figure() simply returns self.figure:
# Source from snippet linked above
def get_figure(self):
"""Return the `.Figure` instance the artist belongs to."""
return self.figure