创建 python 输出的图像

Creating an image of the python output

我在两个 pandas 数据帧之间进行比较,并在终端中打印输出,如下所示:

for key in raw.keys():
    if key == 'jao_atc':
        comparison[key] = raw[key].reindex(data.hourly_index,
                                           fill_value='----')\
            .compare(processed[key], keep_equal=True)
print(comparison['jao_atc'])

输出为:

                          DEtoDK         DKtoDE        
                            self   other   self   other
2021-03-28 23:00:00+00:00   ----  2500.0   ----  1900.0
2021-03-29 01:00:00+00:00   2500  2500.0   1900  1890.0
2021-03-29 04:00:00+00:00   2500  2500.0   1890  1900.0
2021-03-29 05:00:00+00:00   2500  2500.0   1900  1860.0
2021-03-29 07:00:00+00:00   2500  2500.0   1860  1870.0
...                          ...     ...    ...     ...
2021-05-31 19:00:00+00:00   1830  2200.0   2470  2500.0
2021-05-31 20:00:00+00:00   2200  2280.0   2500  2500.0
2021-05-31 21:00:00+00:00   2280  2500.0   2500  2360.0
2021-05-31 22:00:00+00:00   2500  2500.0   2360  2170.0
2021-05-31 23:00:00+00:00   2500     NaN   2170     NaN
[1159 rows x 4 columns]

我想从这个输出生成一个图像,但是我不想截取终端的屏幕截图,而是我正在寻找一个像 create_image_of_the_print_function(comparison['jao_atc']) 这样的函数,它将创建一个终端图像输出。

这可能吗?怎么样?

Export a Pandas dataframe as a table image 适用于数据帧。 是否有更通用的适用于所有输出的解决方案?

预期结果:

image(print(comparison['jao_atc'))


with text-to-image,因为我必须使用转换后的字符串数据帧 to_string(),这会删除终端输出的良好格式:

所以这里有一些解决方案可以满足您的要求,通常您有一个文本并且您希望将其导出为某种格式的图像。我想到的两个建议是:

1- 使用 PIL 库(有关 Add Text on Image using PIL 的更多信息)

2- 使用 openCV 库(关于 https://docs.opencv.org/3.4/dc/da5/tutorial_py_drawing_functions.html 的信息)

这两个库都需要您手动设置图像(例如起始位置、宽高字体等)。但是你可以得到你需要的结果。

编辑:这是一个基于 PIL 的库,可以完全满足您的需要:

https://pypi.org/project/text-to-image/

其用法如下:

import text_to_image

encoded_image_path = text_to_image.encode(stringObject, imageLocation)

编辑 2:

另一种方法是使用 dataframe_image 模块,它将 pandas 数据帧直接转换为图像。

正如您所要求的一般解决方案,您可以首先获得 python 对象的字符串表示形式。

例如,

df = pd.DataFrame({"Customer 1" : ["A","B","C","D","E"],
                  "Customer 2" : ["B","C","D","E","F"],
                  "Customer 3" : ["C","D","E","F","G"]})

字符串表示形式如下(即 str(df)):

  Customer 1 Customer 2 Customer 3
0          A          B          C
1          B          C          D
2          C          D          E
3          D          E          F
4          E          F          G

现在按照 answer 中的步骤将文本转换为图像。

数据帧的输出图像:

对参考答案稍作修改的代码:

import PIL
import PIL.Image
import PIL.ImageFont
import PIL.ImageOps
import PIL.ImageDraw
import pandas as pd

PIXEL_ON = 0  # PIL color to use for "on"
PIXEL_OFF = 255  # PIL color to use for "off"

def text_image(text, font_path=None):
    """Convert text to a grayscale image with black characters on a white background.
    arguments:
    text_path - the content of this file will be converted to an image
    font_path - path to a font file (for example impact.ttf)
    """
    grayscale = 'L'
    # parse the file into lines
    lines = tuple(l.rstrip() for l in text.splitlines())
    # choose a font (you can see more detail in my library on github)
    large_font = 40  # get better resolution with larger size
    font_path = font_path or 'cour.ttf'  # Courier New. works in windows. linux may need more explicit path
    try:
        font = PIL.ImageFont.truetype(font_path, size=large_font)
    except IOError:
        font = PIL.ImageFont.load_default()
        print('Could not use chosen font. Using default.')
    # make the background image based on the combination of font and lines
    pt2px = lambda pt: int(round(pt * 96.0 / 72))  # convert points to pixels
    max_width_line = max(lines, key=lambda s: font.getsize(s)[0])
    # max height is adjusted down because it's too large visually for spacing
    test_string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    max_height = pt2px(font.getsize(test_string)[1])
    max_width = pt2px(font.getsize(max_width_line)[0])
    height = max_height * len(lines)  # perfect or a little oversized
    width = int(round(max_width + 40))  # a little oversized
    image = PIL.Image.new(grayscale, (width, height), color=PIXEL_OFF)
    draw = PIL.ImageDraw.Draw(image)
    # draw each line of text
    vertical_position = 5
    horizontal_position = 5
    line_spacing = int(round(max_height * 0.8))  # reduced spacing seems better
    for line in lines:
        draw.text((horizontal_position, vertical_position),
                  line, fill=PIXEL_ON, font=font)
        vertical_position += line_spacing
    # crop the text
    c_box = PIL.ImageOps.invert(image).getbbox()
    image = image.crop(c_box)
    return image

def main():
    df = pd.DataFrame({"Customer 1" : ["A","B","C","D","E"],
                    "Customer 2" : ["B","C","D","E","F"],
                    "Customer 3" : ["C","D","E","F","G"]})
    image = text_image(str(df))
    image.show()
    image.save("test.png")

if __name__ == '__main__':
    main()

参考: Converting a .txt file to an image in Python