pandas 如何在Jupyter Notebook中的Plot旁边显示数据框

bn31dyow  于 2023-09-29  发布在  其他
关注(0)|答案(5)|浏览(89)

我知道如何在笔记本电脑中显示两个相邻的图(水平),但我不知道是否有一种方法可以显示一个旁边有一个边框的图。我想它可能看起来像这样:

然而,我不能这样做,每当我打印出dataframe时,它就会出现在我的图下面...
Here是一个类似的问题,但我也在同一个单元格中输出了垂直方向的图。
我现在有这个:

# line plots
df_plot[['DGO %chg','DLM %chg']].plot(figsize=(15,5),grid=True)
plt.ylim((-ylim,ylim))

df_plot[['Diff']].plot(kind='area',color='lightgrey',figsize=(15,1))
plt.xticks([])
plt.xlabel('')
plt.ylim((0,ylim_diff))
plt.show()

# scatter plots
plt.scatter(x=df_scat[:-7]['DGO'],y=df_scat[:-7]['DLM'])
plt.scatter(x=df_scat[-7:]['DGO'],y=df_scat[-7:]['DLM'],color='red')
plt.title('%s Cluster Last 7 Days'%asset)
plt.show()

# display dataframe
# display(df_scat[['DGO','DLM']][:10]) <-- prints underneath, not working

其中红色框显示了我希望数据框出现的位置。有没有人有任何关于如何做到这一点的想法?
谢谢你的想法!

7jmck4yq

7jmck4yq1#

我不知道如何控制DataFrame直接显示的位置-但我过去使用的一种方法是将DataFrame渲染为matplotlib表,然后它应该像任何其他matplotlib图一样表现。您可以用途:

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

df = pd.DataFrame()
df['x'] = np.arange(0,11)
df['y'] = df['x']*2

fig = plt.figure(figsize=(8,5))

ax1 = fig.add_subplot(121)
ax1.scatter(x=df['x'],y=df['y'])

ax2 = fig.add_subplot(122)
font_size=14
bbox=[0, 0, 1, 1]
ax2.axis('off')
mpl_table = ax2.table(cellText = df.values, rowLabels = df.index, bbox=bbox, colLabels=df.columns)
mpl_table.auto_set_font_size(False)
mpl_table.set_fontsize(font_size)

cgvd09ve

cgvd09ve2#

另一种可能性是使用html来排序,遵循https://stackoverflow.com/a/44923103/4908900
下面是一个工作示例(可能有更优雅的方法来做到这一点):

prefix = \
"""
 <!DOCTYPE html>
<html>
<head>
<style>
* {
    box-sizing: border-box;
}

.column {
    float: left;
    width: 33.33%;
    padding: 5px;
}

/* Clearfix (clear floats) */
.row::after {
    content: "";
    clear: both;
    display: table;
}
</style>
</head>
<body>

<h2>title</h2>

<div class="row">
  <div class="column">
"""

suffix = \
"""
  </div>
  <div class="column">
    <img src="pic_file.png" alt="Graph" style="width:100%">
  </div>
</div>
</body>
</html>
"""

df = pd.DataFrame(np.arange(36).reshape((6,6)),columns=['A','B','C','D','E','F'])
ax = df.plot(lw=4)
title = "mock data"
fig = ax.get_figure()
fig.savefig(title+".png")
html = prefix.replace('title', title)+df.to_html()+suffix.replace('pic_file.png', title+".png")
display_html(html, raw=True)

gywdnpxw

gywdnpxw3#

您可以随时使用ipwidgets:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import binom

n = 12[enter image description here][1]
p = 0.5
x = np.arange(0, n+1)

binomial_pmf = binom.pmf(x, n, p)
binomial_cdf = binom.cdf(x, n, p)

import ipywidgets as widgets
from ipywidgets import GridspecLayout

out_box1 = widgets.Output(layout={"border":"1px solid green"})
out_box2 = widgets.Output(layout={"border":"1px solid green"})

with out_box1:
    display(pd.DataFrame({'k':x,'binom pmf':np.round(binomial_pmf,4),'binom cdf':np.round(binomial_cdf,4)}).set_index('k'))
    

with out_box2:
    fig, ax1 = plt.subplots(figsize=(10,6))

    ax2 = ax1.twinx()
    ax1.plot(x, binomial_pmf, 'b-')
    ax2.plot(x, binomial_cdf, 'r-')
    plt.title(f"Binomial Distribution (n={n}, p={p})")
    ax1.grid(color = 'green', linestyle = '--', linewidth = 0.5,b=None, which='major', axis='both')

    plt.xticks(np.arange(min(x), max(x)+1, 1.0))
    ax1.set_ylabel('binomial mdf', color='b')
    ax2.set_ylabel('binomial cdf', color='r')

    plt.show()

grid = GridspecLayout(10, 4)
grid[:, 0] = out_box1
grid[:, 1:4] = out_box2

grid

DataFrame - Plot side by side

7gcisfzg

7gcisfzg4#

在jupyter-notebook中,我仅限于绘制图表,也许有人可以在我下面的代码中解决它。至少可以方便地绘制-缩放和拖动,如下一个屏幕截图所示:

代码:

import pandas as pd
import matplotlib.pyplot as plt
import mpld3
from IPython.display import display_html
from bs4 import BeautifulSoup
import inspect

plt.ioff() # prevent plots from being displayed in the output of Jupyter Notebook

def getFig():
    iris_df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv')
    fig, ax = plt.subplots()
    for species, group in iris_df.groupby('species'):
        ax.scatter(group['sepal_length'], group['sepal_width'], label=species)
    ax.set_xlabel('Sepal Length')
    ax.set_ylabel('Sepal Width')
    ax.legend() 
    return fig
    
def get_html_df(caption="iris_df.groupby('species').mean()"):
    iris_df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv')
    html_df = iris_df.groupby('species')[['sepal_length','sepal_width']].mean()\
    .style.set_table_attributes("style='display:inline'")\
    .set_caption(caption)._repr_html_()
    return html_df
    
def main(fig,
         term = 3, # 1, 2 or 3,
         head="Plot", file="deleteme.jpg", caption="HTML-repr's caption tag",
         width=300.0, height=300.0
        ):
       
    html_plot = main_mpld3(fig, width=width, height=height) 
    
    frame = inspect.currentframe()
    args, _, _, values = inspect.getargvalues(frame)
    kwargs = {arg: values[arg] for arg in args}
    [kwargs.pop(key, None) for key in ["fig", "term"]]
    
    match term:
        case 1:
            mpld3.enable_notebook()
            # html_plot not modified
        case 2:
            html_plot = fig2file2html(plt=plt, **kwargs)
        case 3:
            html_plot = fig2file2html(html_plot=html_plot, **kwargs)
    plt.close()
    return html_plot

def main_mpld3(fig, width, height):
    html_plot = mpld3.fig_to_html(fig)
    # print(html_plot)
    
    html_plot = editHTML(html_plot, width, height)
    # print(html_plot)
    return html_plot

def editHTML(html_plot, width, height):
    soup = BeautifulSoup(html_plot, 'html.parser')
    aux = soup.prettify()

    toMatch = '"width": 640.0, "height": 480.0'
    toReplace = f'"width": {width}, "height": {height}' # shows plot, but not inline
    # toReplace = f'"width": {width}, "height": {height}, "style"="display:inline;"' # NOT shows plot
    # toReplace = f'"width": {width}, "height": {height}, "display"="inline"' # NOT shows plot
    modified_html = aux.replace(toMatch, toReplace)
    
    # no effect to inline
    toMatch = '"drawstyle": "default"'
    toReplace = '"drawstyle": "inline"'
    modified_html = modified_html.replace(toMatch, toReplace)
    
    # no effect to inline
    toMatch = '<style>\n</style>'
    toReplace = ''
    modified_html = modified_html.replace(toMatch, toReplace)
    
    soup = BeautifulSoup(modified_html, 'html.parser')
    aux = soup.prettify()
    
    return aux

def fig2file2html(plt=None, html_plot=None, head="Plot", file="deleteme.jpg", caption="HTML-repr's caption tag",
                 width=300.0, height=300.0):
    if (plt is None) and (html_plot is None):
        return Error
    if plt is not None:
        plt.savefig(file)
        html_img = f'<img src={file} alt="" border=3 height={height} width={width}></img>'
    if html_plot is not None:
        hr = 4*"&nbsp;"
        html_img = hr + html_plot + hr
    
    # <img> --> no inline
    html_plot= html_img.replace("<img", "<img style='display:inline ")
    
    # <div> --> no inline
    html_plot= f"""<div style='display:inline'>
    {html_img}
    </div>
    """
    
    # <table> --> YES inline
    html_plot= f"""<table style='display:inline'>
    <caption>{caption}</caption>
    <tr><th>{head}</th><tr>
    <tr><td>
    {html_img}
    </td></tr>
    </table>
    """
    return html_plot

def test01():
    fig = getFig()
    html_df = get_html_df()
    html_plot = main(fig)
    
    print("2 dfs inline:")
    display_html(html_df + html_df, raw=True) # YES success!
    print("df and plot inline:")
    display_html(html_df + html_plot, raw=True) # inline if term=3 or term=2

def test02():
    fig = getFig()
    html_df = get_html_df(caption="")
    html_plot = main(fig,
                     term = 3, # 1, 2 or 3
                     head="", file="deleteme.jpg", caption="",
                     width=650.0, height=650.0,
                    )
    display_html(html_df + html_plot, raw=True)
#test01()
test02()
bzzcjhmw

bzzcjhmw5#

您可以使用%matplotlib inline,然后只需简单地编写代码exdf.head()plt.plot(df['X']),这样%matplotlib inline将绘制数据框以及一个单元格中的图

相关问题