【问题标题】:Can I print pie charts using a for loop in Jupyter?我可以在 Jupyter 中使用 for 循环打印饼图吗?
【发布时间】:2022-08-19 02:02:00
【问题描述】:

我需要使用 for 循环在一个函数中打印多个饼图,最好是水平打印。我的假设是,如果我使用 for 循环打印饼图,所有图表都会生成,但结果会垂直显示。但是,只显示了最后一个数字。

import matplotlib.pyplot as plt
for i in range(3):
    labels = [\'part_1\',\'part_2\',\'part_3\']
    pie_portions = [5,6,7]
    plt.pie(pie_portions,labels=labels,autopct = \'%1.1f%%\')
    plt.title(f\'figure_no : {i+1}\')

    标签: jupyter-notebook


    【解决方案1】:

    您遇到了内置于 Jupyter 笔记本中的 REPL 范例,用于最后一个引用的对象。默认情况下,“读取-评估-打印循环”(REPL) 中的 print(和/或笔记本电脑中的 display)通常仅适用于 Jupyter 输出中的最后一件事。这与为什么如果您有一个已定义的变量,您可以将其作为单元格的最后一行调用,并且它的值将在您不需要print(my_variable) 的情况下显示出来。

    关于你的假设。要让它们都垂直显示,请尝试:

    import matplotlib.pyplot as plt
    for i in range(3):
        labels = ['part_1','part_2','part_3']
        pie_portions = [5,6,7]
        plt.pie(pie_portions,labels=labels,autopct = '%1.1f%%')
        plt.title(f'figure_no : {i+1}')
        plt.show()
    

    这里的所有代码块都是开发的,可以在您的浏览器中正常工作,无需通过mybinder-served sessions launched via here 进行安装,其中环境由 pip 安装包的this list 确定。在这些特定示例中未使用列出的许多内容。


    基于ipywidgets HBox的横向解决方案

    这个初始示例的大部分内容是基于调整我的答案 here,其中 OP 希望单独的 widget tabs 上的图可以依次选择查看。

    import matplotlib.pyplot as plt
    import pandas as pd
    import numpy as np
    import ipywidgets as widgets
    from ipywidgets import HBox
    out1 = widgets.Output()
    out2 = widgets.Output()
    out3 = widgets.Output()
    out = HBox(children = [out1, out2, out3])
    
    data1 = pd.DataFrame(np.random.normal(size = 50))
    data2 = pd.DataFrame(np.random.normal(size = 100))
    data3 = pd.DataFrame(np.random.normal(size = 104))
    
    display(out)
    
    with out1:
        fig1, axes1 = plt.subplots()
        data1.hist(ax = axes1)
        plt.title("test 1")
        plt.show(fig1)
    
    with out2:
        fig2, axes2 = plt.subplots()
        data2.hist(ax = axes2)
        plt.title("test 2")
        plt.show(fig2)
    
    with out3:
        fig3, axes3 = plt.subplots()
        data3.hist(ax = axes3)
        plt.title("test 3")
        plt.show(fig3)
    

    这将使用 HBox 并排显示三个直方图。它还使用在下面的方法中更多使用的子图,并且可以在不使用小部件的情况下完成这项工作。 (我想将小部件作为一个选项包括在内,它显示了我已经拥有框架的“选项卡”显示代码如何可以轻松地适应 HBox 代码,我可以想象,如果您正在制作仪表板,选项会如何派上用场还涉及到小部件。)
    但是,OP 想要饼图。这是一个更接近我对饼图here 所做的解决方案;但是,我发现它有问题,需要一种解决方法:

    import matplotlib.pyplot as plt
    import ipywidgets as widgets
    from ipywidgets import HBox
    out1 = widgets.Output()
    out2 = widgets.Output()
    out3 = widgets.Output()
    out4 = widgets.Output()
    out = HBox(children = [out1, out2, out3, out4])
    
    display(out)
    
    with out1:
        labels = ['part_1','part_2','part_3']
        pie_portions = [5,6,7]
        my_plot = plt.pie(pie_portions,labels=labels,autopct = '%1.1f%%')
        plt.title('figure_no :1')
    
    with out2:
        labels = ['part_1','part_2','part_3']
        pie_portions = [5,6,7]
        my_plot = plt.pie(pie_portions,labels=labels,autopct = '%1.1f%%')
        plt.show(my_plot)
        plt.title('figure_no :2')
    
    with out3:
        labels = ['part_1','part_2','part_3']
        pie_portions = [5,6,7]
        my_plot3 = plt.pie(pie_portions,labels=labels,autopct = '%1.1f%%')
        plt.show(my_plot3)
        plt.title('figure_no :3')
    
    # Easiest way to get three to display was to put a dummy one that doesn't display because of `plt.close()`,
    # based on https://www.adamsmith.haus/python/answers/how-to-hide-a-figure-from-being-shown-in-matplotlib-in-python
    # Otherwise, it messes up third one. This way it only messes up the one it doesn't show.
    # I'm not quite sure what causes this apparent glitch, but this is a nice workaround for now. 
    with out4:
        my_plot4 = plt.pie(pie_portions,labels=labels,autopct = '%1.1f%%')
        plt.show(my_plot4)
        plt.title(' ')
        plt.close()
    

    不太清楚为什么该代码会出现明显的故障,其中添加第四个虚拟饼图至少可以显示所有三个饼图。然而,这并不理想,我发现如果你将子图(见下文)与小部件输出结合起来,那么它可以并排显示三个饼图,而不需要这种解决方法。通过将子图与小部件输出相结合,没有变通方法的更清洁版本:

    import matplotlib.pyplot as plt
    import pandas as pd
    import numpy as np
    import ipywidgets as widgets
    from ipywidgets import HBox
    out1 = widgets.Output()
    out2 = widgets.Output()
    out3 = widgets.Output()
    out = HBox(children = [out1, out2, out3])
    
    with out1:
        fig1, axes1 = plt.subplots()
        labels = ['part_1','part_2','part_3']
        pie_portions = [5,6,7]
        my_plot = plt.pie(pie_portions,labels=labels,autopct = '%1.1f%%')
        plt.title('figure_no :1')
        plt.show(my_plot)
    
    with out2:
        fig2, axes2 = plt.subplots()
        my_plot2 = plt.pie(pie_portions,labels=labels,autopct = '%1.1f%%')
        plt.title('figure_no :2')
        plt.show(my_plot2)
    
    with out3:
        fig3, axes3 = plt.subplots()
        my_plot3 = plt.pie(pie_portions,labels=labels,autopct = '%1.1f%%')
        plt.title('figure_no :3')
        plt.show(my_plot3)
    
    display(out)
    

    基于 Matplotlib 的 subplots 的水平解决方案

    documentation has an example using subplots to display multiple pie plots。这是改编自那三个并排的:

    #Using subplots based on https://matplotlib.org/stable/gallery/pie_and_polar_charts/pie_demo2.html
    import matplotlib.pyplot as plt
    
    # Some data
    labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
    fracs = [15, 30, 45, 10]
    
    # Make figure and axes
    fig, axs = plt.subplots(1, 3)
    
    # A standard pie plot
    axs[0].pie(fracs, labels=labels, autopct='%1.1f%%', shadow=True)
    
    # Shift the second slice using explode
    axs[1].pie(fracs, labels=labels, autopct='%.0f%%', shadow=True,
                  explode=(0, 0.1, 0, 0))
    
    # Another standard pie plot
    axs[2].pie(fracs, labels=labels, autopct='%1.2f%%', shadow=False);
    

    那一个概括为像你这样的 for 循环:

    import matplotlib.pyplot as plt
    # Make figure and axes
    fig, axs = plt.subplots(1, 3)
    
    for i in range(3):
        labels = ['part_1','part_2','part_3']
        pie_portions = [5,6,7]
        axs[i].pie(pie_portions,labels=labels,autopct = '%1.1f%%')
        axs[i].title.set_text(f'figure_no : {i+1}') #title for subplots based on https://stackoverflow.com/a/39133654/8508004
    

    请注意,这些解决方案是使用绘图/绘图对象的活动“内存中”形式完成的。您还可以将绘图保存为图像文件并在笔记本单元格中并排显示生成的图像,使用 HTML 结合<img align ..> 标签,基于hereherehere,或HTML 结合表格,基于here。 (这种在笔记本中并排显示图像的方法被回收here 以自动从图像文件集合中制作 Jupyter RISE 幻灯片。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-08
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 2020-12-05
      • 2021-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多