Saving a figure after invoking pyplot.show() results in an empty file










39














The following example code generates a simple plot, then saves it to 'fig1.pdf', then displays it, then saves it again to 'fig2.pdf'. The first image looks as expected, but the second one is blank (contains a white square). What's actually going on here? The line plt.show() apparently messes something up, but I can't figure out what/how!



import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
plt.plot(x,y)
plt.savefig('fig1.pdf')
plt.show()
plt.savefig('fig2.pdf')









share|improve this question




























    39














    The following example code generates a simple plot, then saves it to 'fig1.pdf', then displays it, then saves it again to 'fig2.pdf'. The first image looks as expected, but the second one is blank (contains a white square). What's actually going on here? The line plt.show() apparently messes something up, but I can't figure out what/how!



    import numpy as np
    import matplotlib.pyplot as plt
    x = np.linspace(-1, 1, 100)
    y = x**2
    plt.plot(x,y)
    plt.savefig('fig1.pdf')
    plt.show()
    plt.savefig('fig2.pdf')









    share|improve this question


























      39












      39








      39


      11





      The following example code generates a simple plot, then saves it to 'fig1.pdf', then displays it, then saves it again to 'fig2.pdf'. The first image looks as expected, but the second one is blank (contains a white square). What's actually going on here? The line plt.show() apparently messes something up, but I can't figure out what/how!



      import numpy as np
      import matplotlib.pyplot as plt
      x = np.linspace(-1, 1, 100)
      y = x**2
      plt.plot(x,y)
      plt.savefig('fig1.pdf')
      plt.show()
      plt.savefig('fig2.pdf')









      share|improve this question















      The following example code generates a simple plot, then saves it to 'fig1.pdf', then displays it, then saves it again to 'fig2.pdf'. The first image looks as expected, but the second one is blank (contains a white square). What's actually going on here? The line plt.show() apparently messes something up, but I can't figure out what/how!



      import numpy as np
      import matplotlib.pyplot as plt
      x = np.linspace(-1, 1, 100)
      y = x**2
      plt.plot(x,y)
      plt.savefig('fig1.pdf')
      plt.show()
      plt.savefig('fig2.pdf')






      python matplotlib






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 8:52









      serv-inc

      13.2k56684




      13.2k56684










      asked Feb 19 '14 at 8:53









      andreasdr

      1,84031624




      1,84031624






















          4 Answers
          4






          active

          oldest

          votes


















          44














          If you want to save the figure after displaying it, you'll need to hold on to the figure instance. The reason that plt.savefig doesn't work after calling show is that the current figure has been reset.



          pyplot keeps track of which figures, axes, etc are "current" (i.e. have not yet been displayed with show) behind-the-scenes. gcf and gca get the current figure and current axes instances, respectively. plt.savefig (and essentially any other pyplot method) just does plt.gcf().savefig(...). In other words, get the current figure instance and call its savefig method. Similarly plt.plot basically does plt.gca().plot(...).



          After show is called, the list of "current" figures and axes is empty.



          In general, you're better off directly using the figure and axes instances to plot/save/show/etc, rather than using plt.plot, etc, to implicitly get the current figure/axes and plot on it. There's nothing wrong with using pyplot for everything (especially interactively), but it makes it easier to shoot yourself in the foot.



          Use pyplot for plt.show() and to generate a figure and an axes object(s), but then use the figure or axes methods directly. (e.g. ax.plot(x, y) instead of plt.plot(x, y), etc) The main advantage of this is that it's explicit. You know what objects you're plotting on, and don't have to reason about what the pyplot state-machine does (though it's not that hard to understand the state-machine interface, either).



          As an example of the "recommended" way of doing things, do something like:



          import numpy as np
          import matplotlib.pyplot as plt

          x = np.linspace(-1, 1, 100)
          y = x**2

          fig, ax = plt.subplots()
          ax.plot(x, y)
          fig.savefig('fig1.pdf')
          plt.show()
          fig.savefig('fig2.pdf')


          If you'd rather use the pyplot interface for everything, then just grab the figure instance before you call show. For example:



          import numpy as np
          import matplotlib.pyplot as plt

          x = np.linspace(-1, 1, 100)
          y = x**2

          plt.plot(x, y)
          fig = plt.gcf()
          fig.savefig('fig1.pdf')
          plt.show()
          fig.savefig('fig2.pdf')





          share|improve this answer






















          • edit nm, figured out this is non interactive
            – tacaswell
            Feb 19 '14 at 17:16







          • 1




            +1, Joe. This, IMO, demonstrates why the usage of the pyplot interface should be kept to a minimum.
            – Paul H
            Feb 19 '14 at 17:30


















          3














          pyplot.show blocks and destroys the plot upon closing. You can use



          plt.show(block=False)


          after which the save to fig2.pdf will work or you can plot it again before saving



          plt.plot(x,y)
          plt.savefig('fig2.pdf')





          share|improve this answer
















          • 2




            That's not what block controls, for what it's worth. block controls whether or the gui toolkit's mainloop will block further execution or run in a separate thread.
            – Joe Kington
            Feb 19 '14 at 14:49


















          1














          I had to run plt.cla() and plt.clf() before plotting the second one. Clear current axes and clear current plot, respectively.






          share|improve this answer




























            0














            If you just want to see the figure before saving, you can call



            plt.ion()


            before plotting, which starts interactive mode, and shows all figures as they are drawn. This mostly removes the need to call plt.show(). You no longer need to close the figures to continue.



            To disable interactive mode again, call plt.ioff().






            share|improve this answer




















              Your Answer






              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "1"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













              draft saved

              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f21875356%2fsaving-a-figure-after-invoking-pyplot-show-results-in-an-empty-file%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              44














              If you want to save the figure after displaying it, you'll need to hold on to the figure instance. The reason that plt.savefig doesn't work after calling show is that the current figure has been reset.



              pyplot keeps track of which figures, axes, etc are "current" (i.e. have not yet been displayed with show) behind-the-scenes. gcf and gca get the current figure and current axes instances, respectively. plt.savefig (and essentially any other pyplot method) just does plt.gcf().savefig(...). In other words, get the current figure instance and call its savefig method. Similarly plt.plot basically does plt.gca().plot(...).



              After show is called, the list of "current" figures and axes is empty.



              In general, you're better off directly using the figure and axes instances to plot/save/show/etc, rather than using plt.plot, etc, to implicitly get the current figure/axes and plot on it. There's nothing wrong with using pyplot for everything (especially interactively), but it makes it easier to shoot yourself in the foot.



              Use pyplot for plt.show() and to generate a figure and an axes object(s), but then use the figure or axes methods directly. (e.g. ax.plot(x, y) instead of plt.plot(x, y), etc) The main advantage of this is that it's explicit. You know what objects you're plotting on, and don't have to reason about what the pyplot state-machine does (though it's not that hard to understand the state-machine interface, either).



              As an example of the "recommended" way of doing things, do something like:



              import numpy as np
              import matplotlib.pyplot as plt

              x = np.linspace(-1, 1, 100)
              y = x**2

              fig, ax = plt.subplots()
              ax.plot(x, y)
              fig.savefig('fig1.pdf')
              plt.show()
              fig.savefig('fig2.pdf')


              If you'd rather use the pyplot interface for everything, then just grab the figure instance before you call show. For example:



              import numpy as np
              import matplotlib.pyplot as plt

              x = np.linspace(-1, 1, 100)
              y = x**2

              plt.plot(x, y)
              fig = plt.gcf()
              fig.savefig('fig1.pdf')
              plt.show()
              fig.savefig('fig2.pdf')





              share|improve this answer






















              • edit nm, figured out this is non interactive
                – tacaswell
                Feb 19 '14 at 17:16







              • 1




                +1, Joe. This, IMO, demonstrates why the usage of the pyplot interface should be kept to a minimum.
                – Paul H
                Feb 19 '14 at 17:30















              44














              If you want to save the figure after displaying it, you'll need to hold on to the figure instance. The reason that plt.savefig doesn't work after calling show is that the current figure has been reset.



              pyplot keeps track of which figures, axes, etc are "current" (i.e. have not yet been displayed with show) behind-the-scenes. gcf and gca get the current figure and current axes instances, respectively. plt.savefig (and essentially any other pyplot method) just does plt.gcf().savefig(...). In other words, get the current figure instance and call its savefig method. Similarly plt.plot basically does plt.gca().plot(...).



              After show is called, the list of "current" figures and axes is empty.



              In general, you're better off directly using the figure and axes instances to plot/save/show/etc, rather than using plt.plot, etc, to implicitly get the current figure/axes and plot on it. There's nothing wrong with using pyplot for everything (especially interactively), but it makes it easier to shoot yourself in the foot.



              Use pyplot for plt.show() and to generate a figure and an axes object(s), but then use the figure or axes methods directly. (e.g. ax.plot(x, y) instead of plt.plot(x, y), etc) The main advantage of this is that it's explicit. You know what objects you're plotting on, and don't have to reason about what the pyplot state-machine does (though it's not that hard to understand the state-machine interface, either).



              As an example of the "recommended" way of doing things, do something like:



              import numpy as np
              import matplotlib.pyplot as plt

              x = np.linspace(-1, 1, 100)
              y = x**2

              fig, ax = plt.subplots()
              ax.plot(x, y)
              fig.savefig('fig1.pdf')
              plt.show()
              fig.savefig('fig2.pdf')


              If you'd rather use the pyplot interface for everything, then just grab the figure instance before you call show. For example:



              import numpy as np
              import matplotlib.pyplot as plt

              x = np.linspace(-1, 1, 100)
              y = x**2

              plt.plot(x, y)
              fig = plt.gcf()
              fig.savefig('fig1.pdf')
              plt.show()
              fig.savefig('fig2.pdf')





              share|improve this answer






















              • edit nm, figured out this is non interactive
                – tacaswell
                Feb 19 '14 at 17:16







              • 1




                +1, Joe. This, IMO, demonstrates why the usage of the pyplot interface should be kept to a minimum.
                – Paul H
                Feb 19 '14 at 17:30













              44












              44








              44






              If you want to save the figure after displaying it, you'll need to hold on to the figure instance. The reason that plt.savefig doesn't work after calling show is that the current figure has been reset.



              pyplot keeps track of which figures, axes, etc are "current" (i.e. have not yet been displayed with show) behind-the-scenes. gcf and gca get the current figure and current axes instances, respectively. plt.savefig (and essentially any other pyplot method) just does plt.gcf().savefig(...). In other words, get the current figure instance and call its savefig method. Similarly plt.plot basically does plt.gca().plot(...).



              After show is called, the list of "current" figures and axes is empty.



              In general, you're better off directly using the figure and axes instances to plot/save/show/etc, rather than using plt.plot, etc, to implicitly get the current figure/axes and plot on it. There's nothing wrong with using pyplot for everything (especially interactively), but it makes it easier to shoot yourself in the foot.



              Use pyplot for plt.show() and to generate a figure and an axes object(s), but then use the figure or axes methods directly. (e.g. ax.plot(x, y) instead of plt.plot(x, y), etc) The main advantage of this is that it's explicit. You know what objects you're plotting on, and don't have to reason about what the pyplot state-machine does (though it's not that hard to understand the state-machine interface, either).



              As an example of the "recommended" way of doing things, do something like:



              import numpy as np
              import matplotlib.pyplot as plt

              x = np.linspace(-1, 1, 100)
              y = x**2

              fig, ax = plt.subplots()
              ax.plot(x, y)
              fig.savefig('fig1.pdf')
              plt.show()
              fig.savefig('fig2.pdf')


              If you'd rather use the pyplot interface for everything, then just grab the figure instance before you call show. For example:



              import numpy as np
              import matplotlib.pyplot as plt

              x = np.linspace(-1, 1, 100)
              y = x**2

              plt.plot(x, y)
              fig = plt.gcf()
              fig.savefig('fig1.pdf')
              plt.show()
              fig.savefig('fig2.pdf')





              share|improve this answer














              If you want to save the figure after displaying it, you'll need to hold on to the figure instance. The reason that plt.savefig doesn't work after calling show is that the current figure has been reset.



              pyplot keeps track of which figures, axes, etc are "current" (i.e. have not yet been displayed with show) behind-the-scenes. gcf and gca get the current figure and current axes instances, respectively. plt.savefig (and essentially any other pyplot method) just does plt.gcf().savefig(...). In other words, get the current figure instance and call its savefig method. Similarly plt.plot basically does plt.gca().plot(...).



              After show is called, the list of "current" figures and axes is empty.



              In general, you're better off directly using the figure and axes instances to plot/save/show/etc, rather than using plt.plot, etc, to implicitly get the current figure/axes and plot on it. There's nothing wrong with using pyplot for everything (especially interactively), but it makes it easier to shoot yourself in the foot.



              Use pyplot for plt.show() and to generate a figure and an axes object(s), but then use the figure or axes methods directly. (e.g. ax.plot(x, y) instead of plt.plot(x, y), etc) The main advantage of this is that it's explicit. You know what objects you're plotting on, and don't have to reason about what the pyplot state-machine does (though it's not that hard to understand the state-machine interface, either).



              As an example of the "recommended" way of doing things, do something like:



              import numpy as np
              import matplotlib.pyplot as plt

              x = np.linspace(-1, 1, 100)
              y = x**2

              fig, ax = plt.subplots()
              ax.plot(x, y)
              fig.savefig('fig1.pdf')
              plt.show()
              fig.savefig('fig2.pdf')


              If you'd rather use the pyplot interface for everything, then just grab the figure instance before you call show. For example:



              import numpy as np
              import matplotlib.pyplot as plt

              x = np.linspace(-1, 1, 100)
              y = x**2

              plt.plot(x, y)
              fig = plt.gcf()
              fig.savefig('fig1.pdf')
              plt.show()
              fig.savefig('fig2.pdf')






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Feb 19 '14 at 15:03

























              answered Feb 19 '14 at 14:58









              Joe Kington

              178k37432397




              178k37432397











              • edit nm, figured out this is non interactive
                – tacaswell
                Feb 19 '14 at 17:16







              • 1




                +1, Joe. This, IMO, demonstrates why the usage of the pyplot interface should be kept to a minimum.
                – Paul H
                Feb 19 '14 at 17:30
















              • edit nm, figured out this is non interactive
                – tacaswell
                Feb 19 '14 at 17:16







              • 1




                +1, Joe. This, IMO, demonstrates why the usage of the pyplot interface should be kept to a minimum.
                – Paul H
                Feb 19 '14 at 17:30















              edit nm, figured out this is non interactive
              – tacaswell
              Feb 19 '14 at 17:16





              edit nm, figured out this is non interactive
              – tacaswell
              Feb 19 '14 at 17:16





              1




              1




              +1, Joe. This, IMO, demonstrates why the usage of the pyplot interface should be kept to a minimum.
              – Paul H
              Feb 19 '14 at 17:30




              +1, Joe. This, IMO, demonstrates why the usage of the pyplot interface should be kept to a minimum.
              – Paul H
              Feb 19 '14 at 17:30













              3














              pyplot.show blocks and destroys the plot upon closing. You can use



              plt.show(block=False)


              after which the save to fig2.pdf will work or you can plot it again before saving



              plt.plot(x,y)
              plt.savefig('fig2.pdf')





              share|improve this answer
















              • 2




                That's not what block controls, for what it's worth. block controls whether or the gui toolkit's mainloop will block further execution or run in a separate thread.
                – Joe Kington
                Feb 19 '14 at 14:49















              3














              pyplot.show blocks and destroys the plot upon closing. You can use



              plt.show(block=False)


              after which the save to fig2.pdf will work or you can plot it again before saving



              plt.plot(x,y)
              plt.savefig('fig2.pdf')





              share|improve this answer
















              • 2




                That's not what block controls, for what it's worth. block controls whether or the gui toolkit's mainloop will block further execution or run in a separate thread.
                – Joe Kington
                Feb 19 '14 at 14:49













              3












              3








              3






              pyplot.show blocks and destroys the plot upon closing. You can use



              plt.show(block=False)


              after which the save to fig2.pdf will work or you can plot it again before saving



              plt.plot(x,y)
              plt.savefig('fig2.pdf')





              share|improve this answer












              pyplot.show blocks and destroys the plot upon closing. You can use



              plt.show(block=False)


              after which the save to fig2.pdf will work or you can plot it again before saving



              plt.plot(x,y)
              plt.savefig('fig2.pdf')






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Feb 19 '14 at 9:21









              miles82

              4,8202823




              4,8202823







              • 2




                That's not what block controls, for what it's worth. block controls whether or the gui toolkit's mainloop will block further execution or run in a separate thread.
                – Joe Kington
                Feb 19 '14 at 14:49












              • 2




                That's not what block controls, for what it's worth. block controls whether or the gui toolkit's mainloop will block further execution or run in a separate thread.
                – Joe Kington
                Feb 19 '14 at 14:49







              2




              2




              That's not what block controls, for what it's worth. block controls whether or the gui toolkit's mainloop will block further execution or run in a separate thread.
              – Joe Kington
              Feb 19 '14 at 14:49




              That's not what block controls, for what it's worth. block controls whether or the gui toolkit's mainloop will block further execution or run in a separate thread.
              – Joe Kington
              Feb 19 '14 at 14:49











              1














              I had to run plt.cla() and plt.clf() before plotting the second one. Clear current axes and clear current plot, respectively.






              share|improve this answer

























                1














                I had to run plt.cla() and plt.clf() before plotting the second one. Clear current axes and clear current plot, respectively.






                share|improve this answer























                  1












                  1








                  1






                  I had to run plt.cla() and plt.clf() before plotting the second one. Clear current axes and clear current plot, respectively.






                  share|improve this answer












                  I had to run plt.cla() and plt.clf() before plotting the second one. Clear current axes and clear current plot, respectively.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Aug 30 '16 at 18:11









                  Nick Desaulniers

                  1,10211236




                  1,10211236





















                      0














                      If you just want to see the figure before saving, you can call



                      plt.ion()


                      before plotting, which starts interactive mode, and shows all figures as they are drawn. This mostly removes the need to call plt.show(). You no longer need to close the figures to continue.



                      To disable interactive mode again, call plt.ioff().






                      share|improve this answer

























                        0














                        If you just want to see the figure before saving, you can call



                        plt.ion()


                        before plotting, which starts interactive mode, and shows all figures as they are drawn. This mostly removes the need to call plt.show(). You no longer need to close the figures to continue.



                        To disable interactive mode again, call plt.ioff().






                        share|improve this answer























                          0












                          0








                          0






                          If you just want to see the figure before saving, you can call



                          plt.ion()


                          before plotting, which starts interactive mode, and shows all figures as they are drawn. This mostly removes the need to call plt.show(). You no longer need to close the figures to continue.



                          To disable interactive mode again, call plt.ioff().






                          share|improve this answer












                          If you just want to see the figure before saving, you can call



                          plt.ion()


                          before plotting, which starts interactive mode, and shows all figures as they are drawn. This mostly removes the need to call plt.show(). You no longer need to close the figures to continue.



                          To disable interactive mode again, call plt.ioff().







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 11 at 8:51









                          serv-inc

                          13.2k56684




                          13.2k56684



























                              draft saved

                              draft discarded
















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f21875356%2fsaving-a-figure-after-invoking-pyplot-show-results-in-an-empty-file%23new-answer', 'question_page');

                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Use pre created SQLite database for Android project in kotlin

                              Darth Vader #20

                              Ondo