how to create hyperlink in piechart
I want to do a pie chart in matplotlib.
This pie chart will be a representation of two variables: male and female.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.
Image map isn't a solution since this variables may change in the future.
Anyone has any 开发者_如何学Goidea how to do this? If it's possible with matplotlib or what program would you recommend.
Thank you!
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.
In the meantime, as @Mark suggested, it's not too hard to dynamically generate an imagemap for the wedges of a pie plot.
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:
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...
You can do this with an imagemap or HTML element overlay controlled by JavaScript/jQuery.
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.
It's a bit harder than the bar graphs I've done this to before, but should work fine.
精彩评论