2012-12-27 12 views
14

chcę uczynić działek jak te z Hacker's Delight:Jak mogę renderować histogramy 3D w pythonie?

enter image description here

Jakie sposoby są nie do osiągnięcia tego celu w Pythonie? Rozwiązanie, które ułatwi interaktywne dopasowanie wykresu (zmiana wycinka X/Y aktualnie obserwowanego) byłoby idealne.

Ani matplotlib, ani moduł mplot3d nie mają tej funkcji AFAICT. Znalazłem mayavi2, ale jest bardzo niezgrabne (nie mogę nawet znaleźć opcji dostosowania rozmiarów) i wydaje się, że działa poprawnie tylko wtedy, gdy uruchamiane jest z ipython.

Alternatywnie gnuplot może działać, ale nie chciałbym uczyć się składni innego języka tylko po to.

+16

ta jest obsługiwana przez matplotlib. Zobacz: http://matplotlib.org/examples/mplot3d/hist3d_demo.html – TJD

+0

@TJD: Dobre znalezisko. Yikes, ten przykład wygląda jednak nieprzenikniony. –

+0

Czy próbowałeś ['barchart()'] (http://docs.enthought.com/mayavi/mayavi/mlab.html). – Developer

Odpowiedz

19

Ponieważ przykład wskazał TJD wydawało „nieprzenikniony” o to zmodyfikowana wersja z kilkoma uwagami, które mogłyby przyczynić się do wyjaśnienia rzeczy:

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