График и уценка рядом в Jupyter Notebook

Я хочу отобразить график и уценку рядом в Jupyter Notebook (для использования в RISE), используя matplotlib. Я нашел следующий ответ, в котором используется plotly,

Покажите интерактивный график и текст Markdown рядом в Jupyter

и просто изменил его, добавив несколько элементов matplotlib

from ipywidgets import widgets, Layout
from IPython.display import display, Javascript, Markdown as md
import numpy as np
import matplotlib.pyplot as plt

def func(x, a, b, c, d):
    return a + b*np.exp(c*x + d)

the_x = np.arange(0, 10, 0.5)
the_y = func(the_x, 1, 1, -1, 2)

fig, ax = plt.subplots()
ax.plot(the_x, the_y)

len_x = len(the_x)

mdout = md(f"""There are {len_x} **elements** of both `the_x`, and `the_y`;

Those values are plotted on the diagram on the left""")


box_layout = Layout(display='flex',
                    flex_flow='row',
                    justify_content='space-around',
                    width='auto'
                   )

hbox1 = widgets.Box(children=[fig, widgets.HTML(mdout._repr_markdown_())], layout=box_layout)
display(hbox1)

Но это не работает со следующим сообщением об ошибке:

TraitError: The 'children' trait of a Box instance contains an Instance of a TypedTuple which expected a Widget, not the Figure <Figure size 640x480 with 1 Axes>.

это примерно вторая строка снизу.

Кто-нибудь может помочь?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В моих руках следующий вариант вашего кода работает как следующий шаг (окончательный вариант см. в разделе «Обновление» ниже):

#based on https://stackoverflow.com/q/78670150/8508004, and adapting to put matplotlib in a widget from https://stackoverflow.com/a/51060721/8508004 (which I think was adapted in some ways from https://github.com/jupyter-widgets/ipywidgets/issues/2821)
from ipywidgets import widgets, Layout
from IPython.display import display, Javascript, Markdown as md
import numpy as np
import matplotlib.pyplot as plt

left_widget = widgets.Output()
def func(x, a, b, c, d):
    return a + b*np.exp(c*x + d)

the_x = np.arange(0, 10, 0.5)
the_y = func(the_x, 1, 1, -1, 2)

with left_widget:
    fig, ax = plt.subplots()
    ax.plot(the_x, the_y)
    plt.show(fig)

len_x = len(the_x)

mdout = md(f"""There are {len_x} **elements** of both `the_x`, and `the_y`;
Those values are plotted on the diagram on the left""")

box_layout = Layout(display='flex',
                    flex_flow='row',
                    justify_content='space-around',
                    width='auto'
                   )

hbox1 = widgets.Box(children=[left_widget, widgets.HTML(mdout._repr_markdown_())], layout=box_layout)
display(hbox1)

Единственным реальным изменением была упаковка объекта графика Matplotlib в контекст виджета Output() ipywidget, который «может захватывать и отображать стандартный вывод, стандартный вывод и расширенный вывод, сгенерированный IPython», а затем использование этого виджета в качестве левой стороны для перечисленных дочерних элементов. в поле ipywidget. (Найдите код, относящийся к left_widget, чтобы увидеть отличия от исходного предоставленного кода.)

Связанные ресурсы:


ОБНОВЛЯТЬ:

Чтобы учесть тот факт, что источник адаптированного решения не включал обработку отображения необработанного кода уценки как полностью визуализированного уценки в области справа, я теперь добавил обработку этого. Вам потребуется установить пакеты для первых двух подходов, которые я предлагаю. (Для markdown2 я поместил команду в связанные блокноты: «Установите ее из работающих блокнотов Juyter с помощью %conda install -c conda-forge markdown2 или %pip install markdown2».).
Первые два решения фактически добавляют рендеринг еще одного элемента уценки, чтобы показать, что их можно быстрее адаптировать. И на самом деле, если вам не нужен текст между обратными кавычками, отображаемый как стиль «код», вы можете выполнить стиль без использования CSS. Подробную информацию см. в сопутствующем блокноте Jupyter, указанном в нижней части этого раздела для получения дополнительной информации. информация.
(На самом деле CSS, используемый в первых двух вариантах, может быть проще, но я поместил здесь полную информацию о CSS для всех элементов, чтобы убедиться, что он работает в полной мере.)

Предлагаемое решение А:

#based on https://stackoverflow.com/q/78670150/8508004, and adapting to put matplotlib in a widget from https://stackoverflow.com/a/51060721/8508004 (which I think was adapted in some ways from https://github.com/jupyter-widgets/ipywidgets/issues/2821)
from ipywidgets import widgets, Layout, HTML
from IPython.display import display
import numpy as np
import matplotlib.pyplot as plt
import markdown

left_widget = widgets.Output()
def func(x, a, b, c, d):
    return a + b*np.exp(c*x + d)

the_x = np.arange(0, 10, 0.5)
the_y = func(the_x, 1, 1, -1, 2)

with left_widget:
    fig, ax = plt.subplots()
    ax.plot(the_x, the_y)
    plt.show(fig)

len_x = len(the_x)

md_content = f"""# (Markdown Heading Rendered) RESULTS:

There are {len_x} **elements** of both `the_x`, and `the_y`;
Those values are plotted on the diagram on the left"""

box_layout = Layout(display='flex',
                    flex_flow='row',
                    justify_content='space-around',
                    width='auto'
                   )
html_content = markdown.markdown(md_content)
markdown_widget = HTML(
    value=f"""
    <style>
    .markdown-body {{
        font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";
        font-size: 16px;
        line-height: 1.5;
        word-wrap: break-word;
    }}
    .markdown-body h1 {{
        padding-bottom: .3em;
        font-size: 2em;
        border-bottom: 1px solid #eaecef;
    }}
    .markdown-body strong {{
        font-weight: 600;
    }}
    .markdown-body code {{
        padding: .2em .4em;
        margin: 0;
        font-size: 85%;
        background-color: rgba(27,31,35,.05);
        border-radius: 3px;
    }}
    </style>
    <div class = "markdown-body">
    {html_content}
    </div>
    """
)
hbox1 = widgets.Box(children=[left_widget, markdown_widget], layout=box_layout)
display(hbox1)

Предлагаемое решение Б:

#based on https://stackoverflow.com/q/78670150/8508004, and adapting to put matplotlib in a widget from https://stackoverflow.com/a/51060721/8508004 (which I think was adapted in some ways from https://github.com/jupyter-widgets/ipywidgets/issues/2821)
from ipywidgets import widgets, Layout
import numpy as np
import matplotlib.pyplot as plt
import markdown2

left_widget = widgets.Output()
def func(x, a, b, c, d):
    return a + b*np.exp(c*x + d)

the_x = np.arange(0, 10, 0.5)
the_y = func(the_x, 1, 1, -1, 2)

with left_widget:
    fig, ax = plt.subplots()
    ax.plot(the_x, the_y)
    plt.show(fig)

len_x = len(the_x)

md_content = f"""# (Markdown Heading Rendered) RESULTS:

There are {len_x} **elements** of both `the_x`, and `the_y`;
Those values are plotted on the diagram on the left"""

box_layout = Layout(display='flex',
                    flex_flow='row',
                    justify_content='space-around',
                    width='auto'
                   )

html_content = markdown2.markdown(md_content)
markdown_widget = widgets.HTML(
    value=f"""
    <style>
    .markdown-body {{
        font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";
        font-size: 16px;
        line-height: 1.5;
        word-wrap: break-word;
    }}
    .markdown-body h1 {{
        padding-bottom: .3em;
        font-size: 2em;
        border-bottom: 1px solid #eaecef;
    }}
    .markdown-body strong {{
        font-weight: 600;
    }}
    .markdown-body code {{
        padding: .2em .4em;
        margin: 0;
        font-size: 85%;
        background-color: rgba(27,31,35,.05);
        border-radius: 3px;
    }}
    </style>
    <div class = "markdown-body">
    {html_content}
    </div>
    """
)
hbox1 = widgets.Box(children=[left_widget, markdown_widget], layout=box_layout)
display(hbox1)

Предлагаемое решение C:

from ipywidgets import widgets, Layout
import numpy as np
import matplotlib.pyplot as plt

left_widget = widgets.Output()
def func(x, a, b, c, d):
    return a + b*np.exp(c*x + d)

the_x = np.arange(0, 10, 0.5)
the_y = func(the_x, 1, 1, -1, 2)

with left_widget:
    fig, ax = plt.subplots()
    ax.plot(the_x, the_y)
    plt.show(fig)

len_x = len(the_x)

md_content = f"""There are {len_x} **elements** of both `the_x`, and `the_y`;
Those values are plotted on the diagram on the left"""

box_layout = Layout(display='flex',
                    flex_flow='row',
                    justify_content='space-around',
                    width='auto'
                   )

def simple_markdown_to_html(text):
    # Handle bold text
    text = text.replace('**', '<strong>', 1).replace('**', '</strong>', 1)
    # Handle inline code
    while '`' in text:
        text = text.replace('`', '<code>', 1).replace('`', '</code>', 1)
    return text

html_content = simple_markdown_to_html(md_content)

markdown_widget = widgets.HTML(
    value=f"""
    <style>
    .markdown-body {{
        font-family: Arial, sans-serif;
        padding: 10px;
    }}
    .markdown-body strong {{
        font-weight: bold;
    }}
    .markdown-body code {{
        background-color: #f0f0f0;
        padding: 2px 4px;
        border-radius: 3px;
        font-family: monospace;
    }}
    </style>
    <div class = "markdown-body">
    {html_content}
    </div>
    """
)

hbox1 = widgets.Box(children=[left_widget, markdown_widget], layout=box_layout)
display(hbox1)

Для получения полной информации просмотрите код и результат, полученный с начальной точки, в файле блокнота Jupyter лучше всего смотреть здесь.

Связанные ресурсы для преобразования текста и оформления уценки:

@Wyne Спасибо за очень полезный ответ. Действительно, код показывает то, что я просил. Еще одна помощь будет оценена по достоинству. Текст уценки отображается в вашем коде как «необработанный». Было бы здорово, если бы оно отображалось «рендеренным». Как вы думаете, это возможно?

T_T 28.06.2024 04:24

@Вайн Удивительно! for _ in range(100): print("Thank you!")

T_T 30.06.2024 09:32

Другие вопросы по теме