Блокнот ipython упорядочивает графики по горизонтали

В настоящее время при создании двух последовательных графиков в ноутбуке ipython они отображаются один под другим:

enter image description here

Мне интересно, есть ли способ показать их в строках, пока в окне не закончится пробел. Итак, для первых двух графиков вывод будет выглядеть следующим образом:

enter image description here

Я понимаю, что могу сделать что-то подобное, упорядочивая подзаголовки в сетке, но мне интересно, можно ли сделать это автоматически, чтобы графики были перенесены на следующую строку, когда пробег заканчивается?

Ответ 1

Это работает для меня в Python 3.5, Jupyter 4.4.0.

Графики "обтекают" при изменении размера окна браузера, чтобы заполнить горизонтальное пространство.

Графики также могут быть разных размеров (попробуйте заменить figsize=(3+i/3,2+i/4) - см. Второе изображение ниже)

(Только что понял, сколько лет этому вопросу; я периодически ищу одну и ту же вещь. Признаюсь, код собран из других примеров в Интернете, но я потерял ссылки сейчас)

import matplotlib.pyplot as plt
import numpy as np
from IPython.display import HTML
import io
import base64


class FlowLayout(object):
    ''' A class / object to display plots in a horizontal / flow layout below a cell '''
    def __init__(self):
        # string buffer for the HTML: initially some CSS; images to be appended
        self.sHtml =  """
        <style>
        .floating-box {
        display: inline-block;
        margin: 10px;
        border: 3px solid #888888;  
        }
        </style>
        """

    def add_plot(self, oAxes):
        ''' Saves a PNG representation of a Matplotlib Axes object '''
        Bio=io.BytesIO() # bytes buffer for the plot
        fig = oAxes.get_figure()
        fig.canvas.print_png(Bio) # make a png of the plot in the buffer

        # encode the bytes as string using base 64 
        sB64Img = base64.b64encode(Bio.getvalue()).decode()
        self.sHtml+= (
            '<div class="floating-box">'+ 
            '<img src="data:image/png;base64,{}\n">'.format(sB64Img)+
            '</div>')

    def PassHtmlToCell(self):
        ''' Final step - display the accumulated HTML '''
        display(HTML(self.sHtml))




oPlot = FlowLayout() # create an empty FlowLayout

# Some fairly regular plotting from Matplotlib
gX = np.linspace(-5,5,100) # just used in the plot example
for i in range(10): # plot 10 charts
    fig, ax = plt.subplots(1, 1, figsize=(3,2)) # same size plots
                           # figsize=(3+i/3,2+i/4)) # different size plots
    ax.plot(gX, np.sin(gX*i)) # make your plot here
    oPlot.add_plot(ax) # pass it to the FlowLayout to save as an image
    plt.close() # this gets rid of the plot so it doesn't appear in the cell


oPlot.PassHtmlToCell()

Charts in Flow Layout

Plots of varying size

Ответ 2

Да, вы можете сделать это:

In [3]: import numpy as np
   ...: xs = np.linspace(0,100,100)
   ...: fig, axs = plt.subplots(nrows=1, ncols=2)
   ...: axs[0].plot(xs, xs * xs)
   ...: axs[1].plot(xs, np.sqrt(xs))
   ...: 

Вывод:

enter image description here

Ответ 3

Довольно точно, что этого не происходит, если не использовать методы подсети или сетки. Что касается размера графика, вы можете указать их размеры с чем-то вроде ax[0].axes([.65, .6, .2, .2]) или plt.subplots(1, 2, figuresize=(12,4)). К сожалению, так устанавливается matplotlib. Если вы используете интерпретатор, вы можете изменить размер графического интерфейса.

Ответ 4

Поскольку вопрос был задан довольно давно, я предложу обновленное решение для тех, кто находит этот вопрос через поисковые системы.

Поскольку Jupyter в значительной степени заменил ноутбук IPython, а Jupyter Lab планирует заменить Jupyter, мое решение реализовано в Jupyter Lab 0.35.4.

В этой среде я считаю чрезвычайно полезным оценить ячейку, которая гласит:

%%html

<style>
    .jp-OutputArea-child {
        display: inline-block;
    }
</style>

Это позволяет лучше использовать вертикальное пространство, позволяя областям вывода, особенно участкам, плавать рядом. Я хотел бы, чтобы более усовершенствованный вариант этого был поведением по умолчанию.

Браузеры в настоящее время не поддерживают родительские селекторы CSS, но, согласно рабочему проекту селекторов 4-го уровня, было бы лучше использовать что-то вроде следующего, если браузеры начнут его поддерживать:

%%html

<style>
    .jp-OutputArea-child:has(> .jp-RenderedImage) {
        display: inline-block;
    }
</style>