我一直在尝试从.CSV文件的同一图上绘制3组(x,y)数据的过程,但是我一无所获。我的数据最初是一个Excel文件,我已将其转换为.CSV文件,并根据以下代码使用pandas将其读入IPython:

from pandas import DataFrame, read_csv
import pandas as pd
# define data location
df = read_csv(Location)
df[['LimMag1.3', 'ExpTime1.3', 'LimMag2.0', 'ExpTime2.0', 'LimMag2.5','ExpTime2.5']][:7]

我的数据采用以下格式:

Type    mag1    time1   mag2    time2   mag3    time3

M0      8.87    41.11   8.41    41.11   8.16    65.78;

...

M6     13.95  4392.03  14.41 10395.13  14.66 25988.32

我试图在同一图上绘制time1 vs mag1time2 vs mag2time3 vs mag3,但是例如,我得到了time.. vs Type的图。对于代码:
df['ExpTime1.3'].plot()

当我想要的是'ExpTime1.3'M0以及x标签M6-'ExpTime1.3'时,我得到'LimMag1.3'(y轴)相对于M0M6(x轴)的图表。
  • 如何获得'ExpTime..''LimMag..'的图,所有3组数据都在同一图上?
  • 如何获取M0值的M6-'LimMag..'标签(也在x轴上)?

  • 由于尝试了Askewchan的解决方案(由于未知原因未返回任何图),所以我发现,如果将数据帧索引(df.index)更改为x轴的值,则可以使用ExpTime获得LimMag vs df['ExpTime1.3'].plot(),的图。 LimMag1.3)。但是,这似乎意味着我必须通过手动输入所需的x轴的所有值以使其成为数据索引,将每个所需的x轴转换为数据框索引。我有很多数据,这种方法太慢了,并且一次只能绘制一组数据,而我需要在一个图上绘制每个数据集的所有3个系列。有办法解决这个问题吗?还是有人可以提供一个原因和解决方案,以使我无法从Askewchan提供的解决方案中得到任何答案?\

    作为对nordev的回应,我再次尝试了第一个版本,但未生成任何图,甚至没有空白图。每次我输入ax.plot命令之一时,都会得到以下类型的输出:
    [<matplotlib.lines.Line2D at 0xb5187b8>],但是当我输入命令plt.show()时,什么都没有发生。
    当我在Askewchan的第二个解决方案中循环后输入plt.show()时,我收到一条错误消息,说AttributeError: 'function' object has no attribute 'show'
    我已经对原始代码做了些摆弄,现在可以通过使索引与x轴相同(LimMag1.3)来获得ExpTime1.3LimMag1.3df['ExpTime1.3'][:7].plot()的关系图,但是我无法获得另一个同一图上的两组数据。如果您有其他建议,我将不胜感激。我正在通过Anaconda 1.5.0(64bit)和Windows 7(64bit)上的spyder使用ipython 0.11.0,python版本是2.7.4。

    最佳答案

    如果我对这个问题以及previous one on the same subject的理解都正确,那么以下内容就是您可以根据需要定制的基本解决方案。

    几个子图:

    请注意,此解决方案将在同一图上垂直输出与光谱类(M0,M1 ...)一样多的子图。如果希望将每个Spectral类的图保存在单独的图中,则代码需要进行一些修改。

    import pandas as pd
    from pandas import DataFrame, read_csv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # Here you put your code to read the CSV-file into a DataFrame df
    
    plt.figure(figsize=(7,5)) # Set the size of your figure, customize for more subplots
    
    for i in range(len(df)):
        xs = np.array(df[df.columns[0::2]])[i] # Use values from odd numbered columns as x-values
        ys = np.array(df[df.columns[1::2]])[i] # Use values from even numbered columns as y-values
        plt.subplot(len(df), 1, i+1)
        plt.plot(xs, ys, marker='o') # Plot circle markers with a line connecting the points
        for j in range(len(xs)):
            plt.annotate(df.columns[0::2][j][-3:] + '"', # Annotate every plotted point with last three characters of the column-label
                         xy = (xs[j],ys[j]),
                         xytext = (0, 5),
                         textcoords = 'offset points',
                         va = 'bottom',
                         ha = 'center',
                         clip_on = True)
        plt.title('Spectral class ' + df.index[i])
        plt.xlabel('Limiting Magnitude')
        plt.ylabel('Exposure Time')
        plt.grid(alpha=0.4)
    
    plt.tight_layout()
    plt.show()
    

    全部位于相同的轴中,按行分组(M0,M1等)

    这是另一种解决方案,可将所有不同的光谱类别绘制在同一轴上,并带有图例标识不同的类别。 plt.yscale('log')是可选的,但是建议您看一下这些值如何跨越这么大的范围。
    import pandas as pd
    from pandas import DataFrame, read_csv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # Here you put your code to read the CSV-file into a DataFrame df
    
    for i in range(len(df)):
        xs = np.array(df[df.columns[0::2]])[i] # Use values from odd numbered columns as x-values
        ys = np.array(df[df.columns[1::2]])[i] # Use values from even numbered columns as y-values
        plt.plot(xs, ys, marker='o', label=df.index[i])
        for j in range(len(xs)):
            plt.annotate(df.columns[0::2][j][-3:] + '"', # Annotate every plotted point with last three characters of the column-label
                         xy = (xs[j],ys[j]),
                         xytext = (0, 6),
                         textcoords = 'offset points',
                         va = 'bottom',
                         ha = 'center',
                         rotation = 90,
                         clip_on = True)
    
    plt.title('Spectral classes')
    plt.xlabel('Limiting Magnitude')
    plt.ylabel('Exposure Time')
    
    plt.grid(alpha=0.4)
    plt.yscale('log')
    plt.legend(loc='best', title='Spectral classes')
    plt.show()
    

    全部位于相同的轴中,按列分组(1.3“,2.0”,2.5“)

    第三种解决方案如下所示,其中数据按系列(列1.3“,2.0”,2.5“)分组,而不是按Spectral类(M0,M1 ...)分组。此示例与
    @askewchan的解决方案。一个区别是,这里的y轴是对数轴,使直线几乎平行。
    import pandas as pd
    from pandas import DataFrame, read_csv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # Here you put your code to read the CSV-file into a DataFrame df
    
    xs = np.array(df[df.columns[0::2]]) # Use values from odd numbered columns as x-values
    ys = np.array(df[df.columns[1::2]]) # Use values from even numbered columns as y-values
    
    for i in range(df.shape[1]/2):
        plt.plot(xs[:,i], ys[:,i], marker='o', label=df.columns[0::2][i][-3:]+'"')
        for j in range(len(xs[:,i])):
            plt.annotate(df.index[j], # Annotate every plotted point with its Spectral class
                         xy = (xs[:,i][j],ys[:,i][j]),
                         xytext = (0, -6),
                         textcoords = 'offset points',
                         va = 'top',
                         ha = 'center',
                         clip_on = True)
    
    plt.title('Spectral classes')
    plt.xlabel('Limiting Magnitude')
    plt.ylabel('Exposure Time')
    
    plt.grid(alpha=0.4)
    plt.yscale('log')
    plt.legend(loc='best', title='Series')
    plt.show()
    

    10-06 08:37