18 votes

Comment puis-je obtenir des histogrammes en 3D ?

Je veux faire des tracés comme ceux-ci à partir de Le plaisir du hacker :

enter image description here

Quels sont les moyens d'y parvenir en Python ? Une solution permettant d'ajuster facilement le graphique de manière interactive (en changeant la tranche de X/Y actuellement observée) serait idéale.

Ni matplotlib ni le module mplot3d n'ont cette fonctionnalité AFAICT. J'ai trouvé mayavi2 mais il est extrêmement lourd (je ne trouve même pas l'option pour ajuster les tailles) et ne semble fonctionner correctement que lorsqu'il est exécuté à partir d'ipython.

Sinon, gnuplot pourrait fonctionner, mais je n'aimerais pas avoir à apprendre la syntaxe d'un autre langage juste pour cela.

36voto

crayzeewulf Points 1487

Depuis l'entrée en vigueur de la exemple signalé par TJD semblait "impénétrable", voici une version modifiée avec quelques commentaires qui peuvent aider à clarifier les choses :

#! /usr/bin/env python
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
#
# Assuming you have "2D" dataset like the following that you need
# to plot.
#
data_2d = [ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
            [6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
            [11, 12, 13, 14, 15, 16, 17, 18 , 19, 20],
            [16, 17, 18, 19, 20, 21, 22, 23, 24, 25],
            [21, 22, 23, 24, 25, 26, 27, 28, 29, 30] ]
#
# Convert it into an numpy array.
#
data_array = np.array(data_2d)
#
# Create a figure for plotting the data as a 3D histogram.
#
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
#
# Create an X-Y mesh of the same dimension as the 2D data. You can
# think of this as the floor of the plot.
#
x_data, y_data = np.meshgrid( np.arange(data_array.shape[1]),
                              np.arange(data_array.shape[0]) )
#
# Flatten out the arrays so that they may be passed to "ax.bar3d".
# Basically, ax.bar3d expects three one-dimensional arrays:
# x_data, y_data, z_data. The following call boils down to picking
# one entry from each array and plotting a bar to from
# (x_data[i], y_data[i], 0) to (x_data[i], y_data[i], z_data[i]).
#
x_data = x_data.flatten()
y_data = y_data.flatten()
z_data = data_array.flatten()
ax.bar3d( x_data,
          y_data,
          np.zeros(len(z_data)),
          1, 1, z_data )
#
# Finally, display the plot.
#
plt.show()

result

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X