Python plt.contour colorbar - PullRequest
       45

Python plt.contour colorbar

0 голосов
/ 23 мая 2018

Я пытаюсь построить график сейсмической волны, используя plt.contour.
У меня есть 3 массива:

  • время (ось x)
  • частота (ось y)
  • амплитуда (ось z)

Пока мои результаты:
plot of the function using plt.contour

Проблема в том, что я хочу изменить масштабирование цветовой шкалы: сделать градацию и не иметь этого белого цвета при низкой амплитуде.Но я не могу этого сделать, хотя я потратил много времени на просмотр документа.

Я прочитал, что plt.pcolormesh здесь не подходит (он просто работает здесь, потому что я в особом случае), но это то, что я хочу получить относительно цветов и цветовой панели:

plot using plt.pcolormesh

Это код, который я написал:

T         = len(time[0])*(time[0][1] - time[0][0])  # multiply ampFFT with T to offset
Z         = abs(ampFFT)*(T)                         # abbreviation

# freq = frequency, ampFFT = Fast Fourier Transform of the amplitude of the wave
# freq, amFFT and time have same dimensions: 40 x 1418 (40 steps of time discretization x steps to have the total time. 2D because it is easier to use) 

maxFreq   = abs(freq).max()                            # maxium frequency for plot boundaries
maxAmpFFT = abs(Z).max()/2                             # maxium ampFFT for plot boundaries of colorbar divided by 2 to scale better with the colors
minAmpFFT = abs(Z).min()

plt.figure(1)
plt.contour(time, freq, Z, vmin=minAmpFFT, vmax=maxAmpFFT)
plt.colorbar()

plt.ylim(0,maxFreq)                                    # 0 to remove the negative frequencies useless here
plt.title("Amplitude intensity regarding to time and frequency")
plt.xlabel('time (in secondes)')
plt.ylabel('frequency (in Hz)')

plt.show()

Спасибо за внимание!

Примечание: на случай, если вас интересует plt.pcolormesh: график полностью запутан, когда я решаю увеличить дискретизацию времени (здесь я делю время на 40, но когда я делю время на 1000,сюжет не правильный, и я хочу иметь возможность разделить время на более мелкие кусочки).

РЕДАКТИРОВАТЬ: Когда я использую plt.contourf вместо plt.contour, я получил этот график: plot with plt.contourf Что тоже не очень убедительно.Я понимаю, почему желтый цвет занимает так много места (это потому, что я установил низкое значение vmax), но я не понимаю, почему на моем графике все еще остается белый цвет.

РЕДАКТИРОВАТЬ 2: Мой учитель составил мои данные, и у меня есть правильные данные.Единственная проблема, которая остается, - это белый фон на моем графике (и темно-синий цвет на левой и правой границе по ни очевидной причине, когда я использую plt.contourf).Несмотря на эти проблемы, самая высокая амплитуда находится в районе 0,5 Гц, что согласуется с работой моего учителя.
Он использовал gnuplot, но, поскольку я не знаю gnuplot, я предпочитаю использовать python.

1 Ответ

0 голосов
/ 24 мая 2018

Решение / Обходной путь, который я нашел

Вот что я сделал для отображения моих данных, как countourf, но без проблем с отображением:
Объяснение : для поверхности я взял abs(freq) вместо просто freq, потому что у меня отрицательные частоты.
Это потому, что при расчете частоты БПФ у вас есть частота, которая повторяется во второй раз, как это:
example of frequency

У вас есть 2 способа получения этой частоты:
- частота положительная , этомассив равен 2 x частоте Найквиста (поэтому, если вы разделите массив на 2, у вас будет вся ваша волна, и она не повторяется).
- частота начинается с отрицательного значения и переходит в положительное значение ,этот массив также имеет частоту 2 x Найквиста (поэтому, если вы удаляете отрицательное значение, у вас есть вся ваша волна, и она не повторяется).

Python fft.fftfreq использует 2-й вариант. plot_surface плохо работает с удалением данных массива (для меня он все еще отображался).Поэтому я сделал значение частоты абсолютным, и проблема исчезла.

fig = plt.figure(1, figsize=(18,15))    # figsize: increase plot size
ax = fig.gca(projection='3d')
surf = ax.plot_surface(time, abs(freq), Z, rstride=1, cstride=1, cmap=cm.magma, linewidth=0, antialiased=False, vmin=minAmpFFT, vmax=maxAmpFFT)

ax.set_zlim(0, maxAmpFFT)
ax.set_ylim(0, maxFreq)

ax.view_init(azim=90, elev=90)          # change view to top view, with axis in the right direction

plt.title("Amplitude intensity (m/Hz^0.5) regarding to time and frequency")
plt.xlabel('x : time (in secondes)')
plt.ylabel('y : frequency (in Hz)')

# ax.yaxis._set_scale('log')            # should be in log, but does not work 


plt.gca().invert_xaxis()                # invert x axis !! MUST BE AFTER X,Y,Z LIM
plt.gca().invert_yaxis()                # invert y axis !! MUST BE AFTER X,Y,Z LIM

plt.colorbar(surf)
fig.tight_layout()
plt.show()

Вот сюжет, который я получил:

3D plot

...