0

Many examples define fig and ax with fig, ax = plt.subplots() and then they directly call functions on the figure object. In contrast, other examples work directly with plt. This answer explains some of the differences, but I am still unclear about two things. First, if I do not create a separate figure object, how do I pass it to another function. For example, when I create a figure object I can pass it to mpld3 to create D3 visualization:

d3plot = mpld3.fig_to_html(fig,template_type="simple")

Second, if I do create the figure object then how do I call functions that I can call on plt on the figure? For example, I would like to able to run the following code and then pass it as a figure to mpld3 as above.

plt.imshow(wordcloud)
plt.axis("off")
plt.show()

The other answer says that plt.subplots() unpacks a tuple. I was not sure if it would unpack what was already on the plt. So I tried:

wordcloud = WordCloud().generate(text)
plt.imshow(wordcloud)
plt.axis("off")
fig, ax = plt.subplots()
d3plot = mpld3.fig_to_html(fig,template_type="simple")

However, this just gives me a black plot, which is consistent with my prior understanding that plt.subplots() creates entirely new figures.

Update Based on the comments, I tried the following:

wordcloud = WordCloud().generate(text)
figTopicWordCloud, ax = plt.subplots()
ax.imshow(wordcloud)
ax.axis('off')
d3plot = mpld3.fig_to_html(figTopicWordCloud, template_type="simple")

While this successfully produced the plot, it did not remove the axes from the figure.

Community
  • 1
  • 1
Michael
  • 13,244
  • 23
  • 67
  • 115
  • I would recommend to always work on axes objects. After creating the figure, get the current axis by calling `ax=plt.gca()` or - for a specific figure object - by calling `ax=fig.gca()`. If your layout includes subplots, you can get subplot axes objects by calling `ax=fig.add_subplot(111)` for example. The methods of axes objects are called differently than the plt functions, have a look at this doc: http://matplotlib.org/api/axes_api.html – Sven Rusch Mar 02 '17 at 21:02
  • I don't follow, what order you're proposing I take in the above example. I also cannot pass the axes to the mpld3.fig_to_html so I'm not sure what the distinction is you're making or how it addresses the present case. – Michael Mar 02 '17 at 22:15
  • Sorry, I misunderstood a part of your question. What you are looking for is `fig=plt.gcf()`. See my answer for details. – Sven Rusch Mar 02 '17 at 22:43
  • Refer to this video of the matplotlib explanation by Andreas Mueller, it might help. https://www.youtube.com/watch?v=OW3oco7nlV4&list=PL_pVmAaAnxIRnSw6wiCpSvshFyCREZmlM&index=3 – tjt Sep 30 '20 at 02:49

1 Answers1

0

When you run something like

plt.imshow()

without explictly creating a figure before, matplotlib creates a new figure object and a new axes object. To access the figure use

fig = plt.gcf()

This returns the current figure. Similarly,

ax = fig.gca()

gives you a reference to the currently active axes in that figure. Calling

fig, ax = plt.subplots()

however, is short for the following:

fig = plt.figure()
ax = fig.add_subplot(111)

The first line will create an entirely new figure object.

A quick solution for your case it to plot the data and access the implicitly created figure after that, like so:

plt.imshow(wordcloud)
plt.axis("off")
fig = plt.gcf()
d3plot = mpld3.fig_to_html(fig, template_type="simple")

You could also explicitly create the figure before actually plotting. Your example would become

fig = plt.figure()
ax = fig.gca()
ax.imshow(wordcloud)
ax.set_axis_off()
d3plot = mpld3.fig_to_html(fig, template_type="simple")

I would usually recommend this solution, because you can always be sure that you are plotting to the correct figure. This is especially useful when handling multiple figures at a time.

Sven Rusch
  • 1,357
  • 11
  • 17
  • Your first method indeed screws up other plots. The second method does not, but the figure produced still has axes. – Michael Mar 02 '17 at 23:13
  • I updated the last part of the answer. This code should produce a figure without visible axes. – Sven Rusch Mar 03 '17 at 08:15
  • Adding `ax.set_axis_off()` still does not suppress the axes. I thought I might have to also add `fig.add_axes(ax)` so I did and that didn't work either. – Michael Mar 03 '17 at 17:54
  • That is strange. The solution I posted in the answer works perfectly fine for me. What version of Python and matplotlib are you using? – Sven Rusch Mar 03 '17 at 18:06
  • Python 2.7.6. and matplotlib 1.4.3. I could probably update matplotlib without breaking anything. I just tried that and in version 2.0.0 this still does not work. When you say it works for you I assume you're taking the final step of viewing the d3 plot rendered in a browser as opposed to just looking at the figure? Thank you for all of your help. – Michael Mar 03 '17 at 18:33
  • I did not actually try to display the d3 plot. However, I did some research and found this issue in the mpld3 issue tracker: https://github.com/mpld3/mpld3/issues/197 It seems that mpld3 simply ignores the fact that you turned off the axis visibility. I think there is not much you can do about that. Except maybe coloring the axis in your background color: http://stackoverflow.com/a/12059429/5480526 mpld3 might also ignore the color, but you could try – Sven Rusch Mar 03 '17 at 19:09