在matplotlib中从.CSV文件创建多行绘图 [英] Make a multiline plot from .CSV file in matplotlib

查看:1581
本文介绍了在matplotlib中从.CSV文件创建多行绘图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试几个星期从.CSV文件绘制3组(x,y)数据在同一个情节,我得到无处。我的数据最初是一个Excel文件,我已经转换为.CSV文件,并使用 pandas 按照下面的代码读入IPython:

 从pandas导入DataFrame,read_csv 
导入pandas为pd
#定义数据位置
df = read_csv
df [['LimMag1.3','ExpTime1.3','LimMag2.0','ExpTime2.0','LimMag2.5','ExpTime2.5']] [:7]

我的资料格式如下:

 键入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 mag1 time2 vs mag2 time3 vs mag3 ,所有在相同的情节,但我得到时间.. vs 的类型,例如。对于代码:

  df ['ExpTime1.3'] plot()

我得到'ExpTime1.3' c> M0 到 M6 (x轴),当我想要的是'ExpTime1.3' vs 'LimMag1.3'与x标签 M0 - M6 。


  1. 如何获得'ExpTime ..'


  2. vs 'LimMag ..' li>

    如何在x轴上获得<$ c> M0 - M6 $ c>'LimMag ..'值(也在x轴上)?


因为尝试askewchan的解决方案,没有返回任何地块的原因未知,我发现,我可以得到一个阴谋 ExpTime vs LimMag 使用 df ['ExpTime1.3']。plot(),如果我将dataframe索引(df.index) x轴(LimMag1.3)。然而,这似乎意味着我必须通过手动输入所需的x轴的所有值来将每个期望的x轴转换为数据帧索引,以使其成为数据索引。我有一个非常多的数据,这种方法太慢了,我只能一次绘制一组数据,当我需要绘制所有3个系列的每个数据集在一个图表上。有办法解决这个问题吗?或者有人可以提供一个理由和解决方案,为什么II没有任何地图与askewchan提供的解决方案?\



响应nordev,我有尝试了第一个版本,bu没有地块生产,甚至一个空图。每次我插入 ax.plot 命令之一,我会得到类型的输出:
[&matplotlib。 line.Line2D at 0xb5187b8>] ,但是当我输入命令 plt.show()什么都没有发生。
当我在askewchan的第二个解决方案中循环之后输入 plt.show()时,我得到一个错误: AttributeError:'function'对象没有属性'show'



我已经做了一些更多的fiddling与我的原始代码,现在可以得到一个 ExpTime1.3 vs LimMag1.3 与代码 df ['ExpTime1.3'] [:7 ] .plot(),使索引与x轴(LimMag1.3)相同,但是我不能在同一个图上得到其他两组数据。我将感谢您可能有任何进一步的建议。我使用ipython 0.11.0通过Anaconda 1.5.0(64位)和spyder在Windows 7(64位),python版本是2.7.4。

解决方案

如果我正确地理解了你,不仅从这个问题,以及你的上一个对同一主题,以下应该是您可以根据自己的需要定制的基本解决方案。



几个子图:



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

  import pandas as pd 
from pandas import DataFrame,read_csv
import numpy as np
import matplotlib.pyplot as plt

#这里你把代码将CSV文件读入一个DataFrame df

plt.figure(figsize =(7,5))#设置图的大小,自定义更多的子图

i在范围内(len(df)):
xs = np.array(df [col.columns [0 :: 2]])[i]#使用奇数列的值作为x值
ys = np.array(df [df.columns [1 :: 2]])[i]#使用偶数列的值作为y值
plt.subplot(len(df),1,i +1)
plt.plot(xs,ys,marker ='o')#用圆点标记连接点的
(len(xs)):
plt.annotate(df.columns [0 :: 2] [j] [ - 3:] +'',#用列标签的最后三个字符注释每个绘制点
xy =(xs [j ],
va ='bottom',
ha ='center'],ys [j]),
xytext =(0,5),
textcoords = ,
clip_on = True)
plt.title('Spectral class'+ df.index [i])
plt.xlabel('Limiting Magnitude')
plt.ylabel '曝光时间')
plt.grid(alpha = 0.4)

plt.tight_layout()
plt.show()



全部在同一轴上,按行(M0,M1,...)分组



得到所有不同的光谱类在同一轴绘制与一个图例识别不同的类。 plt.yscale('log')是可选的,但是看到值如何跨越这么大的范围,建议。

 将pandas导入为pd 
从pandas导入DataFrame,read_csv
导入numpy为np
导入matplotlib.pyplot为plt

#这里你把代码读取CSV文件到一个DataFrame df

for i in range(len(df)):
xs = np.array df [df.columns [0 :: 2]])[i]#使用奇数列的值作为x值
ys = np.array(df [df.columns [1 :: 2]]) [i]#将偶数列的值用作y值
plt.plot(xs,ys,marker ='o',label = df.index [i])
len(xs)):
plt.annotate(df.columns [0 :: 2] [j] [ - 3:] +'',#用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 $ b plt.legend(loc ='best',title ='Spectral classes')
plt.show()



< h1>所有在同一轴上,按列(1.3,2.0,2.5)分组

第三种解决方案如下所示,系列(列1.3,2.0,2.5)而不是Spectral类(M0,M1,...)。这个例子非常类似于
@ askewchan的解决方案。一个区别是这里的y轴是对数轴,使得线几乎平行。

  import pandas as pd 
来自pandas import DataFrame,read_csv
import numpy as np
import matplotlib.pyplot as plt

#这里你把你的代码读取CSV文件到一个DataFrame df

xs = np.array(df [df.columns [0 :: 2]])#使用奇数列的值作为x值
ys = np.array(df [df.columns [1 :: 2]])#使用偶数列的值作为y值

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],#使用Spectral类注释每个绘制点
xy = [$,
texttext =(0,-6),
textcoords ='offset points',
va = 'top',
ha ='center',
clip_on = True)

plt.title('Spectral classes')
plt.xlabel ')
plt.ylabel('Exposure Time')

plt.grid(alpha = 0.4)
plt.yscale('log')
plt.legend (loc ='best',title ='Series')
plt.show()


I've been trying for weeks to plot 3 sets of (x, y) data on the same plot from a .CSV file, and I'm getting nowhere. My data was originally an Excel file which I have converted to a .CSV file and have used pandas to read it into IPython as per the following code:

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]

My data is in the following format:

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

I'm trying to plot time1 vs mag1, time2 vs mag2 and time3 vs mag3, all on the same plot, but instead I get plots of time.. vs Type, eg. for the code:

df['ExpTime1.3'].plot()

I get 'ExpTime1.3' (y-axis) plotted against M0 to M6 (x-axis), when what I want is 'ExpTime1.3' vs 'LimMag1.3', with x-labels M0 - M6.

  1. How do I get 'ExpTime..' vs 'LimMag..' plots, with all 3 sets of data on the same plot?

  2. How do I get the M0 - M6 labels on the x-axis for the 'LimMag..' values (also on the x-axis)?

Since trying askewchan's solutions, which did not return any plots for reasons unknown, I've found that I can get a plot of ExpTimevs LimMagusing df['ExpTime1.3'].plot(),if I change the dataframe index (df.index) to the values of the x axis (LimMag1.3). However, this appears to mean that I have to convert each desired x-axis to the dataframe index by manually inputing all the values of the desired x-axis to make it the data index. I have an awful lot of data, and this method is just too slow, and I can only plot one set of data at a time, when I need to plot all 3 series for each dataset on the one graph. Is there a way around this problem? Or can someone offer a reason, and a solution, as to why I I got no plots whatsoever with the solutions offered by askewchan?\

In response to nordev, I have tried the first version again, bu no plots are produced, not even an empty figure. Each time I put in one of the ax.plotcommands, I do get an output of the type: [<matplotlib.lines.Line2D at 0xb5187b8>], but when I enter the command plt.show()nothing happens. When I enter plt.show()after the loop in askewchan's second solution, I get an error back saying AttributeError: 'function' object has no attribute 'show'

I have done a bit more fiddling with my original code and can now get a plot of ExpTime1.3vs LimMag1.3 with the code df['ExpTime1.3'][:7].plot(),by making the index the same as the x axis (LimMag1.3), but I can't get the other two sets of data on the same plot. I would appreciate any further suggestions you may have. I'm using ipython 0.11.0 via Anaconda 1.5.0 (64bit) and spyder on Windows 7 (64bit), python version is 2.7.4.

解决方案

If I have understood you correctly, both from this question as well as your previous one on the same subject, the following should be basic solutions you could customize to your needs.

Several subplots:

Note that this solution will output as many subplots as there are Spectral classes (M0, M1, ...) vertically on the same figure. If you wish to save the plot of each Spectral class in a separate figure, the code needs some modifications.

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()

All in same Axes, grouped by rows (M0, M1, ...)

Here is another solution to get all the different Spectral classes plotted in the same Axes with a legend identifying the different classes. The plt.yscale('log') is optional, but seeing as how the values span such a great range, it is recommended.

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()

All in same Axes, grouped by columns (1.3", 2.0", 2.5")

A third solution is as shown below, where the data are grouped by the series (columns 1.3", 2.0", 2.5") rather than by the Spectral class (M0, M1, ...). This example is very similar to @askewchan's solution. One difference is that the y-axis here is a logarithmic axis, making the lines pretty much parallel.

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()

这篇关于在matplotlib中从.CSV文件创建多行绘图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆