如何在饼图中创建超链接

时间:2022-11-15 21:53:26

I want to do a pie chart in matplotlib.
This pie chart will be a representation of two variables: male and female.

我想在matplotlib中做一个饼图。这个饼图将代表两个变量:男性和女性。

That's easy to do :)

这很容易:)

What I would like to do next, I'm not even sure if it's possible to do with matplotlib, I would like to make these two variables clickable so if I click on male, I would see another page with information about this, same thing with female.

我接下来想做什么,我甚至不确定是否可以使用matplotlib,我想让这两个变量可以点击,所以如果我点击男性,我会看到另一个页面上有关于此的信息,同样的事情与女性。

Image map isn't a solution since this variables may change in the future.

图像映射不是解决方案,因为此变量将来可能会发生变化。

Anyone has any idea how to do this? If it's possible with matplotlib or what program would you recommend.

任何人都知道如何做到这一点?如果可以使用matplotlib或者你推荐什么程序。

Thank you!

2 个解决方案

#1


5  

While it's not really in a workably stable state yet, have a look at the html5 canvas backend for matplotlib. It looks interesting, anyway, and will probably be the best way to do this sort of thing (interactive webpage with a matplotlib plot) in the future.

虽然它还没有真正处于稳定状态,但请查看matplotlib的html5画布后端。无论如何,它看起来很有趣,并且将来可能是做这种事情的最佳方式(带有matplotlib图的交互式网页)。

In the meantime, as @Mark suggested, it's not too hard to dynamically generate an imagemap for the wedges of a pie plot.

与此同时,正如@Mark建议的那样,为饼图的楔形动态生成图像映射并不太难。

Here's a rough example, that I'm sure you could adapt to whatever web framework you're using.

这是一个粗略的例子,我相信你可以适应你正在使用的任何网络框架。

import matplotlib.pyplot as plt

def main():
    # Make an example pie plot
    fig = plt.figure()
    ax = fig.add_subplot(111)

    labels = ['Beans', 'Squash', 'Corn']
    wedges, plt_labels = ax.pie([20, 40, 60], labels=labels)
    ax.axis('equal')

    make_image_map(fig, wedges, labels, 'temp.html')

def make_image_map(fig, wedges, labels, html_filename):
    """Makes an example static html page with a image map of a pie chart.."""
    #-- Save the figure as an image and get image size ------------------------
    # Be sure to explictly set the dpi when saving the figure
    im_filename = 'temp.png'
    fig.savefig(im_filename, dpi=fig.dpi)

    # Get figure size...
    _, _, fig_width, fig_height = fig.bbox.bounds

    #-- Get the coordinates of each wedge as a string of x1,y2,x2,y2... -------
    coords = []
    for wedge in wedges:
        xy = wedge.get_verts() 

        # Transform to pixel coords
        xy = fig.get_transform().transform(xy) 

        # Format into coord string and convert to <0,0> in top left...
        xy = ', '.join(['%0.2f,%0.2f' % (x, fig_height - y) for x, y in xy])
        coords.append(xy)

    #-- Build web page --------------------------------------------------------
    header = """
    <html>
    <body>
    <img src="{0}" alt="Pie Chart" usemap="#pie_map" width="{1}" height="{2}" />
    """.format(im_filename, fig_width, fig_height)

    # Make the image map
    map = '<map name="pie_map">\n'
    for label, xy in zip(labels, coords):
        href = 'http://images.google.com/images?q={0}'.format(label)
        area = '<area shape="poly" coords="{0}" href="{1}" alt="{2}" />'
        area = area.format(xy, href, label)
        map += '    ' + area + '\n'
    map += '</map>\n'

    footer = """
    </body>
    </html>"""

    # Write to a file...
    with file(html_filename, 'w') as outfile:
        outfile.write(header + map + footer)

if __name__ == '__main__':
    main()

Edit: I just realized that you might not be referring to embedding the plot into a web page... (I assumed that you were from the "display another page" bit in your question.) If you want more of a desktop app, without having to mess with a "full" gui toolkit, you can do something like this:

编辑:我刚才意识到你可能并不是指将剧情嵌入网页......(我假设你是来自你问题中的“显示另一页”。)如果你想要更多的桌面应用程序,无需使用“完整”gui工具包,您可以执行以下操作:

import matplotlib.pyplot as plt

def main():
    # Make an example pie plot
    fig = plt.figure()
    ax = fig.add_subplot(111)

    labels = ['Beans', 'Squash', 'Corn']
    wedges, plt_labels = ax.pie([20, 40, 60], labels=labels)
    ax.axis('equal')

    make_picker(fig, wedges)
    plt.show()

def make_picker(fig, wedges):
    import webbrowser
    def on_pick(event):
        wedge = event.artist
        label = wedge.get_label()
        webbrowser.open('http://images.google.com/images?q={0}'.format(label))

    # Make wedges selectable
    for wedge in wedges:
        wedge.set_picker(True)

    fig.canvas.mpl_connect('pick_event', on_pick)

if __name__ == '__main__':
    main()

Which opens a browser window for a google image search of whatever the wedge is labeled as...

这将打开一个浏览器窗口,用于谷歌图像搜索,无论楔形被标记为......

#2


1  

You can do this with an imagemap or HTML element overlay controlled by JavaScript/jQuery.

您可以使用由JavaScript / jQuery控制的imagemap或HTML元素覆盖来完成此操作。

Essentially, send your chart data to the page along with the chart image, and use JS to create the elements with the links according to the specification of the data.

实质上,将图表数据与图表图像一起发送到页面,并使用JS根据数据规范创建包含链接的元素。

It's a bit harder than the bar graphs I've done this to before, but should work fine.

它比我以前做过的条形图有点难,但应该可以正常工作。

#1


5  

While it's not really in a workably stable state yet, have a look at the html5 canvas backend for matplotlib. It looks interesting, anyway, and will probably be the best way to do this sort of thing (interactive webpage with a matplotlib plot) in the future.

虽然它还没有真正处于稳定状态,但请查看matplotlib的html5画布后端。无论如何,它看起来很有趣,并且将来可能是做这种事情的最佳方式(带有matplotlib图的交互式网页)。

In the meantime, as @Mark suggested, it's not too hard to dynamically generate an imagemap for the wedges of a pie plot.

与此同时,正如@Mark建议的那样,为饼图的楔形动态生成图像映射并不太难。

Here's a rough example, that I'm sure you could adapt to whatever web framework you're using.

这是一个粗略的例子,我相信你可以适应你正在使用的任何网络框架。

import matplotlib.pyplot as plt

def main():
    # Make an example pie plot
    fig = plt.figure()
    ax = fig.add_subplot(111)

    labels = ['Beans', 'Squash', 'Corn']
    wedges, plt_labels = ax.pie([20, 40, 60], labels=labels)
    ax.axis('equal')

    make_image_map(fig, wedges, labels, 'temp.html')

def make_image_map(fig, wedges, labels, html_filename):
    """Makes an example static html page with a image map of a pie chart.."""
    #-- Save the figure as an image and get image size ------------------------
    # Be sure to explictly set the dpi when saving the figure
    im_filename = 'temp.png'
    fig.savefig(im_filename, dpi=fig.dpi)

    # Get figure size...
    _, _, fig_width, fig_height = fig.bbox.bounds

    #-- Get the coordinates of each wedge as a string of x1,y2,x2,y2... -------
    coords = []
    for wedge in wedges:
        xy = wedge.get_verts() 

        # Transform to pixel coords
        xy = fig.get_transform().transform(xy) 

        # Format into coord string and convert to <0,0> in top left...
        xy = ', '.join(['%0.2f,%0.2f' % (x, fig_height - y) for x, y in xy])
        coords.append(xy)

    #-- Build web page --------------------------------------------------------
    header = """
    <html>
    <body>
    <img src="{0}" alt="Pie Chart" usemap="#pie_map" width="{1}" height="{2}" />
    """.format(im_filename, fig_width, fig_height)

    # Make the image map
    map = '<map name="pie_map">\n'
    for label, xy in zip(labels, coords):
        href = 'http://images.google.com/images?q={0}'.format(label)
        area = '<area shape="poly" coords="{0}" href="{1}" alt="{2}" />'
        area = area.format(xy, href, label)
        map += '    ' + area + '\n'
    map += '</map>\n'

    footer = """
    </body>
    </html>"""

    # Write to a file...
    with file(html_filename, 'w') as outfile:
        outfile.write(header + map + footer)

if __name__ == '__main__':
    main()

Edit: I just realized that you might not be referring to embedding the plot into a web page... (I assumed that you were from the "display another page" bit in your question.) If you want more of a desktop app, without having to mess with a "full" gui toolkit, you can do something like this:

编辑:我刚才意识到你可能并不是指将剧情嵌入网页......(我假设你是来自你问题中的“显示另一页”。)如果你想要更多的桌面应用程序,无需使用“完整”gui工具包,您可以执行以下操作:

import matplotlib.pyplot as plt

def main():
    # Make an example pie plot
    fig = plt.figure()
    ax = fig.add_subplot(111)

    labels = ['Beans', 'Squash', 'Corn']
    wedges, plt_labels = ax.pie([20, 40, 60], labels=labels)
    ax.axis('equal')

    make_picker(fig, wedges)
    plt.show()

def make_picker(fig, wedges):
    import webbrowser
    def on_pick(event):
        wedge = event.artist
        label = wedge.get_label()
        webbrowser.open('http://images.google.com/images?q={0}'.format(label))

    # Make wedges selectable
    for wedge in wedges:
        wedge.set_picker(True)

    fig.canvas.mpl_connect('pick_event', on_pick)

if __name__ == '__main__':
    main()

Which opens a browser window for a google image search of whatever the wedge is labeled as...

这将打开一个浏览器窗口,用于谷歌图像搜索,无论楔形被标记为......

#2


1  

You can do this with an imagemap or HTML element overlay controlled by JavaScript/jQuery.

您可以使用由JavaScript / jQuery控制的imagemap或HTML元素覆盖来完成此操作。

Essentially, send your chart data to the page along with the chart image, and use JS to create the elements with the links according to the specification of the data.

实质上,将图表数据与图表图像一起发送到页面,并使用JS根据数据规范创建包含链接的元素。

It's a bit harder than the bar graphs I've done this to before, but should work fine.

它比我以前做过的条形图有点难,但应该可以正常工作。