首页 > 解决方案 > Hertzsprung 图和嵌套字典

问题描述

我正在尝试使用 Python 从维基百科复制 Hertzsprung 图的图表:https ://en.wikipedia.org/wiki/Hertzsprung%E2%80%93Russell_diagram#/media/File:HRDiagram.png 。

我是 Python 新手,正在尝试利用嵌套字典来完成包含一小部分数据的代码:

32349   379.21 -1.44    0.009
30438    10.43 -0.62    0.164
69673    88.85 -0.05    1.239
71683   742.12 -0.01    0.710
91262   128.93  0.03   -0.001
24608    77.29  0.08    0.795
24436     4.22  0.18   -0.030
37279   285.93  0.40    0.432
7588     22.68  0.45   -0.158
27989     7.63  0.45    1.500
68702     6.21  0.61   -0.231
97649   194.44  0.76    0.221
60718    10.17  0.77   -0.243
21421    50.09  0.87    1.538
65474    12.44  0.98   -0.235
80763     5.40  1.06    1.865
37826    96.74  1.16    0.991
113368  130.08  1.17    0.145
62434     9.25  1.25   -0.238
102098    1.01  1.25    0.092 

如果可能的话,我能否帮助我找到一个适用于嵌套字典的循环?另外,我可以帮助创建将在图中显示的轴吗?

到目前为止我的代码:

import numpy as np
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt

astronomical_unit = 1.495978707e11  # meters
meters_to_light_years = 1./9.4607e15


def star_colormap(star_b_minus_vs):
    # Create color map from B-V = -0.33 (#7070ff) to 1.40 (#ff7f7f)
    # yellow = #ffff7f at B-V = 0.81
    number_of_gradient_points = 256
    white_index = int((0.33 / (0.33 + 1.40)) * number_of_gradient_points)
    yellow_index = int(((0.81 + .33) / (0.33 + 1.40)) * number_of_gradient_points)
    print(white_index, yellow_index, number_of_gradient_points)
    color_values = np.ones((number_of_gradient_points, 4))
    # Red values
    color_values[:white_index, 0] = np.linspace(112 / number_of_gradient_points,
                                                255 / number_of_gradient_points,
                                                white_index)
    color_values[white_index:yellow_index, 0] = np.linspace(255 / number_of_gradient_points,
                                                            255 / number_of_gradient_points,
                                                            yellow_index - white_index)
    color_values[yellow_index:, 0] = np.linspace(255 / number_of_gradient_points,
                                                 255 / number_of_gradient_points,
                                                 number_of_gradient_points - yellow_index)
    # Green values
    color_values[:white_index, 1] = np.linspace(112 / number_of_gradient_points,
                                                255 / number_of_gradient_points,
                                                white_index)
    color_values[white_index:yellow_index, 1] = np.linspace(255 / number_of_gradient_points,
                                                            255 / number_of_gradient_points,
                                                            yellow_index - white_index)
    color_values[yellow_index:, 1] = np.linspace(255 / number_of_gradient_points,
                                                 127 / number_of_gradient_points,
                                                 number_of_gradient_points - yellow_index)
    # Blue values
    color_values[:white_index, 2] = np.linspace(255 / number_of_gradient_points,
                                                255 / number_of_gradient_points,
                                                white_index)
    color_values[white_index:yellow_index, 2] = np.linspace(255 / number_of_gradient_points,
                                                            127 / number_of_gradient_points,
                                                            yellow_index - white_index)
    color_values[yellow_index:, 2] = np.linspace(127 / number_of_gradient_points,
                                                 127 / number_of_gradient_points,
                                                 number_of_gradient_points - yellow_index)
    new_colormap = ListedColormap(color_values)

    # Scale B-V values from 0 to 1
    scaled_b_minus_vs = (star_b_minus_vs - np.amin(star_b_minus_vs)) / (
            np.amax(star_b_minus_vs) - np.amin(star_b_minus_vs))

    return scaled_b_minus_vs, new_colormap


def parallax_to_distance(parallax):
    """Take parallax in milliarcseconds and convert to distance in meters"""
    parallax_in_radians = (parallax / 1000. / 3600.) * (2 * np.pi / 360.)
    distance = astronomical_unit / np.tan(parallax_in_radians)
    return distance


def apparent_to_absolute_magnitude(apparent_magnitude, distance):
    """Calculate absolute magnitude from apparent magnitude and distance in meters"""
    distance_in_parsecs = distance / (648000. * astronomical_unit / np.pi)
    absolute_magnitude = apparent_magnitude - 5*np.log10(distance_in_parsecs) + 5
    return absolute_magnitude


def read_file(filename):
    """Read four column data from HIPPARCOS satellite and return a nested dictionary"""
    # Read in as nested dictionary
    hipparcos_data = {'(star catalog number':
                           { 'parallax' : [] , 'apparent_magnitude' : [] , 'blue_minus_visual' : [] }}
    return hipparcos_data


# Apply read function to the data file and produce a nested dictionary


# Loop over star catalog number key
#       Call parallax_to_distance on parallax value and assign to new value
#       Call apparent_to_absolute_magnitude on apparent magnitude value and assign to new value
#       Append absolute magnitude for current star into NumPy array of absolute magnitudes
#           named star_absolute_magnitudes
#       Append B-V value for current star into NumPy array of B-V values
#           named star_b_minus_vs

# Use dark style for plot
plt.style.use('dark_background')

# Reverse the absolute magnitude so that negative values appear on top
star_absolute_magnitudes = np.negative(star_absolute_magnitudes)

# Get color map to match star colors
scaled_b_minus_v, hr_diagram_colormap = star_colormap(star_b_minus_vs)

# Create axes labels

# Scatter plot of B-V vs absolute magnitude
plt.scatter(star_b_minus_vs, star_absolute_magnitudes, c=scaled_b_minus_v, cmap=hr_diagram_colormap)
plt.show()

标签: pythondictionarynested

解决方案


def read_file(filename):
    with open(filename) as fp:
        res = {}    
        for line in fp:
            star, parallax, magnitude, bmv = line.split()
            res[star] = {
                'parallax': float(parallax),
                'magnitude': float(magnitude),
                'blue_minus_visual': float(bmv)
            }

    return res


stars = read_file('data.txt')

# Loop over star catalog number key
for star in stars:

    # Call parallax_to_distance on parallax value and assign to new value
    stars[star]['parallax'] = parallax_to_distance(stars[star]['parallax'])

    #  Call apparent_to_absolute_magnitude on apparent magnitude value and assign to new value
    stars[star]['magnitude'] = apparent_to_absolute_magnitude(stars[star]['magnitude'])

推荐阅读