2012-12-27 10 views
14

Voglio fare trame come queste da Hacker's Delight:Come posso rendere istogrammi 3D in pitone?

enter image description here

Quali modi ci sono per raggiungere questo obiettivo in Python? Una soluzione che rende semplice la regolazione interattiva del grafico (cambiando la porzione di X/Y attualmente osservata) sarebbe l'ideale.

Né matplotlib né il modulo di mplot3d hanno questa funzionalità AFAICT. Ho trovato mayavi2 ma è estremamente goffo (non riesco nemmeno a trovare l'opzione per la regolazione delle dimensioni) e solo sembra funzionare correttamente quando viene eseguito da ipython.

In alternativa, gnuplot potrebbe funzionare, ma non mi piacerebbe dover imparare un'altra sintassi della lingua solo per questo.

+16

Questo è supportato da matplotlib. Vedere questo: http://matplotlib.org/examples/mplot3d/hist3d_demo.html – TJD

+0

@TJD: buona scoperta. Yikes, quell'esempio sembra impenetrabile. –

+0

Hai provato [ 'barchart()'] (http://docs.enthought.com/mayavi/mayavi/mlab.html). – Developer

risposta

19

Dal momento che l'esempio indicato da TJD sembrava "impenetrabile" qui è una versione modificata con alcuni commenti che potrebbero aiutare a chiarire le cose:

#! /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()