将pandas数据框处理为小提琴图。

17

我正在从Excel电子表格中读取数据。每个场景(S1到S6)都有多个观测值。当我将数据读入我的数据框df时,它看起来如下:

      Scenario        LMP
0           S1 -21.454544
1           S1 -20.778094
2           S1 -20.027689
3           S1 -19.747170
4           S1 -20.814405
5           S1 -21.955406
6           S1 -23.018960
...
12258       S6 -34.089906
12259       S6 -34.222814
12260       S6 -26.712010
12261       S6 -24.555973
12262       S6 -23.062616
12263       S6 -20.488411

我想创建一个小提琴图,其中每个场景都有一个不同的小提琴。我对Pandas和数据框架很陌生,尽管在过去的一天里进行了大量的研究和测试,但我仍然无法找到一种优雅的方法来传递一些引用到我的数据框架(将其拆分为每个场景的不同系列),以便在axes.violinplot()语句中使用。例如,我尝试了以下内容,但它不起作用。在我的axes.violinplot语句上,我得到一个“ValueError:无法将大小为1752的序列复制到具有维度2的数组轴”的错误。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# load data into a dataframe
df = pd.read_excel('Modeling analysis charts.xlsx',
                   sheetname='lmps',
                   parse_cols=[7,12],
                   skiprows=0,
                   header=1)

fontsize = 10

fig, axes = plt.subplots()

axes.violinplot(dataset = [[df.loc[df.Scenario == 'S1']],
                           [df.loc[df.Scenario == 'S2']],
                           [df.loc[df.Scenario == 'S3']],
                           [df.loc[df.Scenario == 'S4']],
                           [df.loc[df.Scenario == 'S5']],
                           [df.loc[df.Scenario == 'S6']]
                          ]
                )
axes.set_title('Day Ahead Market')

axes.yaxis.grid(True)
axes.set_xlabel('Scenario')
axes.set_ylabel('LMP ($/MWh)')

plt.show()

啊,我在尝试使用未解析数据的整个列(df.iloc[:,1])作为概念证明时使用了减号。最终,我需要将数据值全部变成它们的相反数,但我可以稍后解决这个问题。现在先把它拿掉。我仍然会得到一个新的错误,但会更新帖子以反映这一点。我也会删除位置语句,因为默认应该是可以的。 - Emily Beth
我在调用时遇到了 KeyError 错误。有什么建议吗?(请参见 https://dev59.com/_LDma4cB1Zd3GeqPCdrj) - sisdog
2个回答

23

创建绘图数据集时需要注意。在问题的代码中,你有一个包含一个DataFrame的列表,但是你只需要一个包含单列DataFrame的列表。

因此,你还需要仅从筛选后的DataFrame中获取“LMP”列数据,否则violinplot将不知道该绘制哪一列。

这里是一个接近原始代码的可行示例:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt


x = np.random.poisson(lam =3, size=100)
y = np.random.choice(["S{}".format(i+1) for i in range(6)], size=len(x))
df = pd.DataFrame({"Scenario":y, "LMP":x})

fig, axes = plt.subplots()

axes.violinplot(dataset = [df[df.Scenario == 'S1']["LMP"].values,
                           df[df.Scenario == 'S2']["LMP"].values,
                           df[df.Scenario == 'S3']["LMP"].values,
                           df[df.Scenario == 'S4']["LMP"].values,
                           df[df.Scenario == 'S5']["LMP"].values,
                           df[df.Scenario == 'S6']["LMP"].values ] )

axes.set_title('Day Ahead Market')
axes.yaxis.grid(True)
axes.set_xlabel('Scenario')
axes.set_ylabel('LMP ($/MWh)')

plt.show()

输入图像描述


如果有人在使用此示例时遇到KeyError问题,请参考https://dev59.com/_LDma4cB1Zd3GeqPCdrj - sisdog
@sisdog 感谢您指出这一点。我已经更正了答案。这是最近一些matplotlib版本中的疏忽,所以我们可能会在某个时候修复它。在那之前,使用.values(即numpy数组)是绘制pandas系列的可靠方法。 - ImportanceOfBeingErnest

13

您可以使用seaborn。在这种情况下,导入seaborn,然后使用小提琴图来可视化情境。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# load data into a dataframe
df = pd.read_excel('Modeling analysis charts.xlsx',
                   sheetname='lmps',
                   parse_cols=[7,12],
                   skiprows=0,
                   header=1)
fontsize = 10

fig, axes = plt.subplots()
# plot violin. 'Scenario' is according to x axis, 
# 'LMP' is y axis, data is your dataframe. ax - is axes instance
sns.violinplot('Scenario','LMP', data=df, ax = axes)
axes.set_title('Day Ahead Market')

axes.yaxis.grid(True)
axes.set_xlabel('Scenario')
axes.set_ylabel('LMP ($/MWh)')

plt.show()

在这里输入图片描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接