Как правильно написать синтаксис для выполнения и построения графика для операции l oop? - PullRequest
1 голос
/ 08 марта 2020

Я пытаюсь создать для l oop, который использует определенную функцию (B_lambda) и принимает значения длины волны и температуры для получения значений интенсивности. то есть я хочу, чтобы l oop взял функцию B_lambda и прошел через все значения в моем диапазоне длин волн для каждой температуры в списке температур. Тогда я хочу представить результаты. Я не очень хорошо разбираюсь в синтаксисе и перепробовал много способов, но ничто не дает того, что мне нужно, и я в основном получаю ошибки. Я понятия не имею, как использовать a для l oop для построения графика, и все онлайн-источники, которые я проверил, не помогли мне с использованием определенной функции в a для l oop. Ниже я приведу свой последний код, который содержит наименьшее количество ошибок, с сообщением об ошибке:

import matplotlib.pylab as plt
import numpy as np
from astropy import units as u
import scipy.constants
%matplotlib inline

#Importing constants to use.
h = scipy.constants.h
c = scipy.constants.c
k = scipy.constants.k

wavelengths= np.arange(1000,30000)*1.e-10
temperature=[3000,4000,5000,6000]

for lam in wavelengths:
    for T in temperature:
        B_lambda = ((2*h*c**2)/(lam**5))*((1)/(np.exp((h*c)/(lam*k*T))-1))
        plt.figure()
        plt.plot(wavelengths,B_lambda)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-73b866241c49> in <module>
     17         B_lambda = ((2*h*c**2)/(lam**5))*((1)/(np.exp((h*c)/(lam*k*T))-1))
     18         plt.figure()
---> 19         plt.plot(wavelengths,B_lambda)
     20 
     21 

/usr/local/lib/python3.6/dist-packages/matplotlib/pyplot.py in plot(scalex, scaley, data, *args, **kwargs)
   2787     return gca().plot(
   2788         *args, scalex=scalex, scaley=scaley, **({"data": data} if data
-> 2789         is not None else {}), **kwargs)
   2790 
   2791 

/usr/local/lib/python3.6/dist-packages/matplotlib/axes/_axes.py in plot(self, scalex, scaley, data, *args, **kwargs)
   1663         """
   1664         kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D._alias_map)
-> 1665         lines = [*self._get_lines(*args, data=data, **kwargs)]
   1666         for line in lines:
   1667             self.add_line(line)

/usr/local/lib/python3.6/dist-packages/matplotlib/axes/_base.py in __call__(self, *args, **kwargs)
    223                 this += args[0],
    224                 args = args[1:]
--> 225             yield from self._plot_args(this, kwargs)
    226 
    227     def get_next_color(self):

/usr/local/lib/python3.6/dist-packages/matplotlib/axes/_base.py in _plot_args(self, tup, kwargs)
    389             x, y = index_of(tup[-1])
    390 
--> 391         x, y = self._xy_from_xy(x, y)
    392 
    393         if self.command == 'plot':

/usr/local/lib/python3.6/dist-packages/matplotlib/axes/_base.py in _xy_from_xy(self, x, y)
    268         if x.shape[0] != y.shape[0]:
    269             raise ValueError("x and y must have same first dimension, but "
--> 270                              "have shapes {} and {}".format(x.shape, y.shape))
    271         if x.ndim > 2 or y.ndim > 2:
    272             raise ValueError("x and y can be no greater than 2-D, but have "

ValueError: x and y must have same first dimension, but have shapes (29000,) and (1,)```

1 Ответ

0 голосов
/ 08 марта 2020

Первое, что нужно отметить (и это незначительно), это то, что astropy не требуется для запуска вашего кода. Таким образом, вы можете упростить операторы импорта.

import matplotlib.pylab as plt
import numpy as np
import scipy.constants
%matplotlib inline

#Importing constants to use.
h = scipy.constants.h
c = scipy.constants.c
k = scipy.constants.k


wavelengths= np.arange(1000,30000,100)*1.e-10 # here, I chose steps of 100, because plotting 29000 datapoints takes a while
temperature=[3000,4000,5000,6000]

Во-вторых, чтобы немного прибавить l oop, вы можете написать вспомогательную функцию, которую вы будете вызывать из себя l oop:

def f(lam, T):
    return ((2*h*c**2)/(lam**5))*((1)/(np.exp((h*c)/(lam*k*T))-1))

теперь вы можете собрать выходные данные вашей функции вместе с входными параметрами, например, в списке кортежей:

outputs = []

for lam in wavelengths:
    for T in temperature:
        outputs.append((lam, T, f(lam, T)))

Поскольку вы изменяете как длину волны, так и температуру, 3D График имеет смысл:

from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111, projection='3d')

ax.plot(*zip(*outputs))

enter image description here

Альтернативой может быть отображение данных в виде изображения с использованием цвета для обозначения выходных данных функции.

Я также включаю альтернативный метод для генерации данных в этом. Поскольку функция f может принимать массивы в качестве входных данных, вы можете подавать одну температуру за раз, а вместе с ней - все длины волн одновременно.

# initialise output as array with proper shape
outputs = np.zeros((len(wavelengths), len(temperature)))

for i, T in enumerate(temperature):
    outputs[:,i] = f(wavelengths, T)

Теперь вывод представляет собой большую матрицу, которую можно визуализировать как изображение:

fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(outputs, aspect=10e8, interpolation='none', 
          extent=[
              np.min(temperature),
              np.max(temperature),
              np.max(wavelengths),
              np.min(wavelengths)]
         )

enter image description here

...