【问题标题】:Plot horizontal bars inside a pandas dataframe在熊猫数据框中绘制水平条
【发布时间】:2018-08-28 03:41:12
【问题描述】:

我有一个销售 pandas 数据框,其中每一行代表一个公司名称,有四列显示过去五年的当前、最小、最大和平均销售额。

我想知道是否有办法在数据框内绘制最小值、最大值、平均值、当前水平条。

只是给你一个具体的例子: https://libguides.lib.umanitoba.ca/bloomberg/fixedincome

如果您查看“范围”列,这正是我试图在数据框中复制的内容。我找到了 matplotlib boxplot,但我认为我不能在数据框中绘制它们。

您知道任何解决方案吗?

【问题讨论】:

  • 我没有理解“在数据框内绘图”的意思。我们从不在数据框中绘制任何内容。我们使用数据框中的值并绘制它们。
  • @ShridharRKulkarni 如果您查看附加的链接,您是否看到那些显示橙色点表示当前平均值的水平线、一个表示当前(最近)值的蓝点以及它们的水平线与水平线极值的距离与最小值和最大值的关系。所以我在问python是否有类似的东西。
  • 这个真的不清楚。我可以想象你想要类似于 Matplotlib- Creating a table with line plots in cells 的东西,只是带有箱线图?但请写一个清晰的问题,并附上问题描述,解释您想要实现的目标以及阻碍您实现目标的原因。此外,如果这是关于熊猫数据框的,请使用相应的标签。
  • @ImportanceOfBeingErnest 好的,所以除了直接分享屏幕截图之外,我不知道我还能做什么。在 Excel 中,伙计们,我说的是 excel,我可以构建一个宏,以便在普通表中可视化最小值、最大值、平均值和当前值。现在,我不知道是否有 matplotlib 代码可以像颜色图一样在数据框中可视化这些数据。因此我标记了 python 和 matplotlib。绘图框显示超过 4 个值,我只需要水平绘制四个值。
  • 如果你们不明白,请避免像“这真的不清楚”这样无用的 cmets,因为您需要做的就是看一个图表。

标签: python dataframe matplotlib


【解决方案1】:

好的,基于 NK_ 帮助和以下内容: Matplotlib- Creating a table with line plots in cells?

我设法把它放在一起:

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

df = pd.DataFrame({'Name':["A","B","C","E","F"],'current':[3,4,7,6,6], 'minimum':[1,3,2,4,1], 'maximum':[10,14,11,7,10], 'average':[8,5,9,5,3]})


data = np.random.rand(100,5)
col1 = df["Name"]
col2 = df["current"]
col2colors = ["red", "g", "r", "r", "r"]
col3 = df["average"]
finalsc = "D+"

fig, axes = plt.subplots(ncols=5, nrows=5, figsize=(6,2.6),
                         gridspec_kw={"width_ratios":[1,1,1,3,3]})
fig.subplots_adjust(0.05,0.05,0.95,0.95, wspace=0.02, hspace=0.05)   #wspace, hspace --> bordi interni grigi della tabella

for ax in axes.flatten():
    ax.tick_params(labelbottom=0, labelleft=0, bottom=0, top=0, left=0, right=0)
    ax.ticklabel_format(useOffset=False, style="plain")
    for _,s in ax.spines.items():
        s.set_visible(True)

border = fig.add_subplot(111)
border.tick_params(labelbottom=0, labelleft=0, bottom=0, top=0, left=0, right=0)
border.set_facecolor("None")

text_kw = dict(ha="center", va="bottom", size=15)
for i,ax in enumerate(axes[:,0]):
    ax.text(0.5, 0.2, col1[i], transform=ax.transAxes, **text_kw)

for i,ax in enumerate(axes[:,1]):
    ax.text(0.5, 0.2, "{:.2f}".format(col2[i]),transform=ax.transAxes, **text_kw)
    ax.set_facecolor(col2colors[i])
    ax.patch.set_color(col2colors[i])

for i,ax in enumerate(axes[:,2]):
    ax.text(0.5, 0.2, "{:.2f}".format(col3[i]),transform=ax.transAxes, **text_kw)

for i,ax in enumerate(axes[:,3]):
    ax.plot(data[:,i], color="green", linewidth=1)

for i,ax in enumerate(axes[:,4]):
    ax.plot([df['minimum'][index],df['maximum'][index]],[0,0],zorder=0)      
    ax.scatter(df['current'][index],0,zorder=1)
    ax.scatter(df['average'][index],0,zorder=2)

plt.show()

说实话,我不知道我整理的代码是否是我能用过的最好的代码,还有很多部分我需要理解。

请问,我想问的最后一个问题是: 有人可以帮我在这个表中添加第一“行”,我们用粗体显示每列的标题吗? 谢谢

【讨论】:

    【解决方案2】:

    我不完全确定您到底在寻找什么,所以如果您需要其他任何东西,请告诉我。

    我使用 pandas 为图表创建了一些虚拟数据和 matplotlib。

    import pandas as pd
    import matplotlib.pyplot as plt
    df = pd.DataFrame({'current':[3,4,7], 'minimum':[1,3,2], 'maximum':[10,14,11], 'average':[8,5,9]})
    
    #   average  current  maximum  minimum
    #0        8        3       10        1
    #1        5        4       14        3
    #2        9        7       11        2
    

    现在是重要的部分。我从图像中重新创建了您的示例。此循环遍历数据框中的每一行,即您的公司。结果是与您的公司一样多的图表。

    • ax.plot 创建一条从 minimum 值到 maximum 值。
    • ax.scattercurrentaverage 值创建点。

    当然,您必须稍微调整一下图表,使其看起来像您想要的那样。

    for index,row in df.iterrows(): 
        fig, ax = plt.subplots()
        ax.plot([df['minimum'][index],df['maximum'][index]],[0,0],zorder=0)      
        ax.scatter(df['current'][index],0,zorder=1)
        ax.scatter(df['average'][index],0,zorder=2)
    

    这将是第一家公司的图表。

    编辑(参见@Andrea 的评论):将绘制的数据更紧密地放在一起

    您可以按照上面的方法,但调整图表的样式。

    for index,row in df.iterrows(): 
        fig, ax = plt.subplots(figsize=(7, 0.2)) # adjust the width and height of the graphs
        ax.plot([df['minimum'][index],df['maximum'][index]],[0,0],color='gray',zorder=0)      
        ax.scatter(df['current'][index],0,zorder=1)
        ax.scatter(df['average'][index],0,marker='D',zorder=2)   
        plt.xticks([]) # disable the ticks of the x-axis
        plt.yticks([]) # disable the ticks of the y-axis   
        for spine in plt.gca().spines.values(): # disable the border around the graphs
            spine.set_visible(False)
    

    这看起来非常接近您在问题中发布的图像。

    【讨论】:

    • 这实际上很有帮助。你认为有可能将这些图按字面意思放在一列中,彼此之间没有空格吗?
    • @Andrea 我编辑了我的帖子。如果您需要不同的东西,请告诉我。
    • 这太棒了!请问最后一个问题。如果你不能帮助我完全理解。因此,最终目标是使用您的代码和您创建的带有子图的图,并将它们以类似表格的格式显示。我检查了 ImportanceOfBeingErnest 在这里做了什么:stackoverflow.com/questions/47779560/… 所以你的问题是:我们可以将你创建的图表作为子图列(第 6 列)并在第 1 列中包含公司名称,第 2 列是平均值,第 3 列最小值的值,第 4 列的最大值,第 5 列的当前值。价值?
    • 我正在尝试将您的解决方案与该链接上的解决方案相结合,但代码的某些部分对我来说真的很难理解。请不要认为我很懒,但老实说,我对 matlplotlib 仍然不是很好。无论如何谢谢你。安德里亚
    猜你喜欢
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2016-01-07
    • 2019-08-30
    • 2020-01-14
    • 1970-01-01
    • 2018-03-11
    相关资源
    最近更新 更多