2010-09-21 8 views
3

Je veux faire un graphique à secteurs dans matplotlib.
Ce camembert sera une représentation de deux variables: masculin et féminin.comment créer un lien hypertexte dans piechart

facile à faire :)

Ce que je voudrais faire ensuite, je ne suis même pas sûr s'il est possible de faire avec matplotlib, je voudrais faire ces deux variables cliquable donc si je clique sur mâle, je verrais une autre page avec des informations à ce sujet, la même chose avec une femme.

La carte d'image n'est pas une solution puisque ces variables peuvent changer dans le futur.

Quelqu'un a une idée de comment faire cela? Si c'est possible avec matplotlib ou quel programme recommanderiez-vous.

Merci!

Répondre

5

Bien qu'il ne soit pas vraiment dans un état fonctionnellement stable, jetez un oeil à la html5 canvas backend for matplotlib. Cela semble intéressant, de toute façon, et sera probablement la meilleure façon de faire ce genre de chose (page web interactive avec une intrigue matplotlib) dans le futur. En attendant, comme l'a suggéré @Mark, il n'est pas trop difficile de générer dynamiquement un imagemap pour les coins d'un graphe de tarte.

Here's a rough example, que je suis sûr que vous pourriez adapter à n'importe quel framework Web que vous utilisez.

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: Je viens de réaliser que vous ne pourriez pas référence à intégrer la parcelle dans une page web ... (je suppose que vous étiez à partir du bit « afficher une autre page » dans votre question.) Si vous veulent plus d'une application de bureau, sans avoir à jouer avec un toolkit « complète », vous pouvez faire quelque chose comme ceci:

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() 

qui ouvre une fenêtre de navigateur pour une recherche d'image Google de ce que le coin est étiqueté comme ...

+0

Merci Joe, beaucoup de détails et d'exemples. Très sympa :) J'essaye de l'implémenter avec django et html. Mais je ne comprends pas vraiment ton code HTML. Normalement, je mets le lien vers l'image ou l'endroit où il est enregistré – pavid

+0

@Patricia - Eh bien, c'est tout ce que je fais dans le premier exemple ... Il enregistre simplement l'image sur le disque, insère un '', puis génère une carte d'image pour l'image enregistrée basée sur les coins dans le camembert. (La surbrillance de la syntaxe de Stackoverflow est un peu bancale avec toutes les chaînes imbriquées '" ',' '', et '" "" ') La clé est pour la boucle sous le' '# - Récupère les coordonnées de chaque coin. .' "bit. Je suis juste en train d'attraper les sommets pour chaque coin, les convertissant en coordonnées de pixels pour l'image sauvegardée, et générant une chaîne avec ces coordonnées.J'espère que cela pourra aider! –

+0

bien je pense que mon erreur est quelque part là parce que quand je passe les variables au modèle, il ne fait rien – pavid

1

Vous pouvez le faire avec une superposition d'éléments imagemap ou HTML contrôlée par JavaScript/jQuery. Pour l'essentiel, envoyez vos données de graphique à la page avec l'image du graphique et utilisez JS pour créer les éléments avec les liens en fonction de la spécification des données.

C'est un peu plus difficile que les graphiques à barres que j'ai déjà fait, mais cela devrait fonctionner correctement.

+0

Si les données étaient toujours les mêmes, ce serait vraiment facile, une carte image ferait l'affaire. Mais les données peuvent varier, il faut donc calculer seul. js ou jq ferait cela? – pavid

+0

Oui, vous pouvez créer et modifier des éléments de n'importe quelle façon imaginable en utilisant javascript/jquery. Je verrai si je peux arriver avec un échantillon de code plus tard. –

Questions connexes