Есть ли модуль python, который сделает участок водопада, такой как MATLAB? Я googled 'numpy водопад', 'scipy водопад', и 'matplotlib водопад', но ничего не нашел.
Пейзаж водопада сюжет?
Ответ 1
Посмотрите mplot3d:
# copied from
# http://matplotlib.sourceforge.net/mpl_examples/mplot3d/wire3d_demo.py
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X, Y, Z = axes3d.get_test_data(0.05)
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
plt.show()
Я не знаю, как добиться хороших результатов, чем Matlab.
Если вы хотите больше, вы также можете посмотреть MayaVi: http://mayavi.sourceforge.net/
Ответ 2
Вы можете создать водопад в matplotlib, используя класс PolyCollection. Посмотрите этот конкретный пример, чтобы узнать больше о том, как сделать водопад с помощью этого класса.
Кроме того, этот блог может оказаться полезным, поскольку автор показывает, что вы можете получить некоторую "визуальную ошибку" в определенной ситуации (в зависимости от выбранного угла обзора).
Ниже приведен пример водопада, созданного с помощью matplotlib (изображение из поста в блоге):
(источник: austringer.net)
Ответ 3
Тип Википедии График водопада можно получить так же:
import numpy as np
import pandas as pd
def waterfall(series):
df = pd.DataFrame({'pos':np.maximum(series,0),'neg':np.minimum(series,0)})
blank = series.cumsum().shift(1).fillna(0)
df.plot(kind='bar', stacked=True, bottom=blank, color=['r','b'])
step = blank.reset_index(drop=True).repeat(3).shift(-1)
step[1::3] = np.nan
plt.plot(step.index, step.values,'k')
test = pd.Series(-1 + 2 * np.random.rand(10), index=list('abcdefghij'))
waterfall(test)
Ответ 4
Я сгенерировал функцию, которая копирует поведение водопада Matlab в Matplotlib. То есть:
- Он генерирует трехмерную форму в виде множества независимых и параллельных двухмерных кривых
- Его цвет происходит из карты цветов в значениях z
Я начал с двух примеров в документации по matplotlib: многоцветные линии и несколько линий на трехмерном графике. Из этих примеров я видел только возможность рисовать линии, цвет которых меняется в зависимости от заданной карты цветов в соответствии с ее значением z, следующим за примером, который изменяет входной массив для рисования линии сегментами по 2 точкам и устанавливает цвет сегмента равным среднее значение z между этими двумя точками.
Таким образом, учитывая входные матрицы n,m
, матрицы X
, Y
и Z
, функция проходит по наименьшему измерению между n,m
, чтобы построить каждую из независимых линий водопада в виде набора линий из двух точек. сегменты, как описано выше.
def waterfall_plot(fig,ax,X,Y,Z,**kwargs):
'''
Make a waterfall plot
Input:
fig,ax : matplotlib figure and axes to populate
Z : n,m numpy array. Must be a 2d array even if only one line should be plotted
X,Y : n,m array
kwargs : kwargs are directly passed to the LineCollection object
'''
# Set normalization to the same values for all plots
norm = plt.Normalize(Z.min().min(), Z.max().max())
# Check sizes to loop always over the smallest dimension
n,m = Z.shape
if n>m:
X=X.T; Y=Y.T; Z=Z.T
m,n = n,m
for j in range(n):
# reshape the X,Z into pairs
points = np.array([X[j,:], Z[j,:]]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
# The values used by the colormap are the input to the array parameter
lc = LineCollection(segments, cmap='plasma', norm=norm, array=(Z[j,1:]+Z[j,:-1])/2, **kwargs)
line = ax.add_collection3d(lc,zs=(Y[j,1:]+Y[j,:-1])/2, zdir='y') # add line to axes
fig.colorbar(lc) # add colorbar, as the normalization is the same for all
# it doesent matter which of the lc objects we use
ax.auto_scale_xyz(X,Y,Z) # set axis limits
Таким образом, графики, похожие на водопад Matlab, могут быть легко сгенерированы с теми же входными матрицами, что и график поверхности Matplotlib:
import numpy as np; import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from mpl_toolkits.mplot3d import Axes3D
# Generate data
x = np.linspace(-2,2, 500)
y = np.linspace(-2,2, 60)
X,Y = np.meshgrid(x,y)
Z = np.sin(X**2+Y**2)-.2*X
# Generate waterfall plot
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
waterfall_plot(fig,ax,X,Y,Z,linewidth=1.5,alpha=0.5)
ax.set_xlabel('X'); ax.set_ylabel('Y'); ax.set_zlabel('Z')
fig.tight_layout()
Функция предполагает, что при генерации сетки, массив x
является самым длинным, и по умолчанию линии имеют фиксированный y, а его координата x меняется. Однако, если размер массива y
больше, матрицы транспонируются, генерируя строки с фиксированным x. Таким образом, генерация сетки с инвертированными размерами (len(x)=60
и len(y)=500
) дает:
Чтобы узнать, каковы возможности аргумента **kwargs
, обратитесь к документации класса LineCollection и ее методам set_
.