Python 在数据框中插入熊猫图的图像

Python 在数据框中插入熊猫图的图像,python,pandas,dataframe,matplotlib,Python,Pandas,Dataframe,Matplotlib,我已经为这个问题绞尽脑汁好几天了,所以我想让社区帮忙。我在Jupyter笔记本中使用Python3,但希望最终将其变成一个脚本 问题 我有一个熊猫数据框架,它有三列(查询、URL、趋势)。所有的数据都在工作。我甚至可以为每个查询生成绘图图像;但是,我无法在数据框的趋势列中显示趋势图的图像。它只显示AxesSubplot(0.125,0.125;0.775x0.755)。没有错误消息(尽管我已经听到了一些) 我尝试过的 我已经查看了fig.savefig(),它似乎接近于我所需要的,但无法100%

我已经为这个问题绞尽脑汁好几天了,所以我想让社区帮忙。我在Jupyter笔记本中使用Python3,但希望最终将其变成一个脚本

问题

我有一个熊猫数据框架,它有三列(查询、URL、趋势)。所有的数据都在工作。我甚至可以为每个查询生成绘图图像;但是,我无法在数据框的趋势列中显示趋势图的图像。它只显示
AxesSubplot(0.125,0.125;0.775x0.755)
。没有错误消息(尽管我已经听到了一些)

我尝试过的

我已经查看了fig.savefig(),它似乎接近于我所需要的,但无法100%确定如何在我的情况下工作,因为它输出所有绘图,每个查询需要一个绘图

我也试过了,但我还没能为我的代码实现它(虽然很接近)

它也非常接近我正在寻找的结果实现(以及我当前的实现),但我不知道如何获取我刚刚创建的绘图图像的HTML URL。此外,理想情况下,图像不需要保存,因为这可能是通过电子邮件发送的每日报告

迄今为止的结果

数据帧

查询URL趋势

0玛格丽特·特鲁多。。。AxesSubplot(0.125,0.125;0.775x0.755)

尼克·科德罗。。。AxesSubplot(0.125,0.125;0.775x0.755)

等等

这些是数据框下方代码中的趋势图

等等

看起来一切正常,但

预期结果

数据框应与上面相同,但我希望
AxesSubplot(0.125,0.125;0.775x0.755)
成为趋势图的图像

当前代码

from googlesearch import search

import pandas as pd
import matplotlib.pyplot as plt
from pytrends.request import TrendReq

pytrend = TrendReq()

def trending_searches(geo):
    geo_lower = str.lower(geo) # Need geolocation to be lowercase to work
    df = pytrend.trending_searches(pn=geo_lower)

    queries = [] # Hold all processed queries

    for index, row in df.iterrows():
        i = str(row)
        j = str.strip(i, '0    ')
        k = j.split("\n", 1)[0]
        queries.append(k)

    # Gets the trend data 
    trend = pd.DataFrame(get_trend(queries))

    # Gets the first URL from each query on Google
    urls = pd.DataFrame(get_urls(queries))

    # column lable
    trend.columns = ["Trend"]
    urls.columns = ["URL"]
    df.columns = ['Query']

    #Concat all into one dataframe
    result = pd.concat([df, urls, trend], axis=1)

    #html = result.to_html() #Convert to HTML for emails

    return result #html

def get_trend(kw: list) -> list:

    query = kw

    # Get trend data
    my_results_list = []
    for j in query:    
        pytrend.build_payload(kw_list=[j])
        df = pytrend.interest_over_time()
        my_results_list.append(df)

    # Plot trend data
    plots = []
    for i in range(len(my_results_list)):
        if my_results_list[i].empty == True: # To mitigate queries that have no data
            plots.append("No data avaiable")
        else:
            plot = my_results_list[i].plot(kind='line', figsize=(5,1), sharex=True)
            plots.append(plot)

    return plots

def get_urls(kw: list) -> list:

    query = kw

    my_results_list = []
    for j in query:    
        for i in search(j,        # The query you want to run
                    tld = 'ca',  # The top level domain
                    lang = 'en',  # The language
                    num = 10,     # Number of results per page
                    start = 0,    # First result to retrieve
                    stop = 1,  # Last result to retrieve
                    pause = 2.0,  # Lapse between HTTP requests
                   ):

            my_results_list.append(i)

    return my_results_list

trending_searches('Canada')

一旦您已经构建了
fig
,就必须将其转换为二进制,然后将其作为值存储到var中

buf = io.BytesIO()
fig.savefig(buf, format='png')
buf.seek(0)
string = base64.b64encode(buf.read())
然后,您必须聚合与输出图像对应的HTML标记

uri = 'data:image/png;base64,' + urllib.parse.quote(string)
html = '<img src = "%s"/>' % uri

然后我做了
dataframe.to_html(escape=False)
,它确实生成了带有图像的html

显然,我在这里使用的是jupyter,但是使用HTML构建后,您应该能够像以前一样打印它,而不会出现进一步的问题

最后,我得出了下面的代码:

将熊猫作为pd导入
将matplotlib.pyplot作为plt导入
将numpy作为np导入
导入urllib、urllib.parse、base64、io、base64
从IPython.core.display导入显示,HTML
#模拟数据帧
查询=[]
url=[]
趋势=[]
对于范围(10)内的i:
#保存无花果
plt图(np.rand.rand(5));
图=plt.gcf();
#将其存储为二进制文件
buf=io.BytesIO()
图savefig(buf,format='png')
buf.seek(0)
string=base64.b64编码(buf.read())
#用HTML标记补充
uri='数据:图像/png;base64,“+urllib.parse.quote(字符串)
html=''%uri
#清除matplotlib的缓存
plt.clf()
#附加结果
query.append(i+1)
url.append(“google.com”)
追加(html)
#构建df
df=pd.DataFrame({“query”:query,“url”:url,“trend”:trend})
#解析为html
html=df.to_html(escape=False)

你能检查一下它是否有效吗?:)

嘿,凯奥!这真的很有帮助。我的问题与我原来的问题相似。所以,我尝试了你的代码作为独立的,这是有效的!然后我将其集成到我的代码中。它现在将值放入数据帧,但不会显示图像。经过几次试验后,我添加了plt.show()以确保为每一行创建一个绘图。是的,是的。然后尝试调用显示HTML中包装的函数。显示(HTML(趋势搜索('Canada'))。不知道我错过了什么,但我们显然很接近!我想出来了。调用to_html()时需要添加escape=False如何将其另存为.xlsx?从Pandas dataframe中,可以选择将其另存为excel
df.to_excel('path/file.xlsx')
。但不确定它是否能正确显示图像。
for i in range(10):
    ...
    query.append(i+1)
    url.append("google.com")
    trend.append(html)

df = pd.DataFrame({"query": query,"url": url,"trend":trend})
df.head()