Сюжетный сюжет не любит зацикленных баров? - PullRequest
0 голосов
/ 21 апреля 2020

Я пытаюсь создать простой pdf-файл для подзаголовка, состоящего из одной гистограммы и одной таблицы данных:

Функция Bar и table работает, но когда я пытаюсь создать под-график, график дает следующую ошибку :

ValueError:
    Invalid element(s) received for the 'data' property of        
        Invalid elements include

Я написал следующее: Разве не нравится, что я зациклил следы бара?

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

import plotly
import plotly.graph_objects as go
import plotly.figure_factory as ff
import os
import numpy as np
from plotly.subplots import make_subplots
import pandas as pd


def build_barchart(df,columns):

    x = df.City.unique() # City column should always be the x axis
    fig = go.Figure()
    fig.update_layout(barmode='stack')
    for column in columns:
        Y=df[column].tolist()
        fig.add_trace(go.Bar(name=column,x=x,y=Y))

    return fig 

def build_table(df):

    table = ff.create_table(df)
    return table

def create_pdf(df,columns):

    fig = make_subplots(rows=1, cols=2)

    fig.add_trace(
        build_barchart(df,columns),
        row=1, col=1
    )

    fig.add_trace(
        build_table(df),
        row=1, col=2
    )


    if not os.path.exists("images"):
        os.mkdir("images")


    fig.write_image("images/fig1.pdf")
    return

После создания функций сборки я пытаюсь их использовать ...

df = pd.read_csv('DATA.csv', delimiter=';')
columns=['%Something','%Dogs','%Cats','%Cars']

table = build_table(df)
bars =  build_barchart(df,columns)

fig = make_subplots(rows=1, cols=2)

fig.add_trace(
    bars,
    row=1, col=1
)

fig.add_trace(
    table,
    row=1, col=2
)

fig.show()

данные испытаний

City;%Something;%Dogs;%Cats;%Cars;Nr Alarms;Nr Block
USA;60;10;5;25;1;1
CANADA;20;10;5;65;2;2
MEXICO;90;5;5;0;3;3
SWEDEN;10;10;5;75;4;4

Ответы [ 2 ]

0 голосов
/ 22 апреля 2020

Пожалуйста, не принимайте это как ответ. Учитывая, что в вашем коде есть некоторые подводные камни, я добавляю полированную версию. В частности, в случае, если у вас есть дублированные страны, x = df.City.astype('str').unique() не будет хорошо работать с Y, и вы должны организовать / проверить свои данные, прежде чем строить график.

import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots

df = pd.DataFrame({
 'City': {0: 'USA', 1: 'CANADA', 2: 'MEXICO', 3: 'SWEDEN'},
 '%Something': {0: 60, 1: 20, 2: 90, 3: 10},
 '%Dogs': {0: 10, 1: 10, 2: 5, 3: 10},
 '%Cats': {0: 5, 1: 5, 2: 5, 3: 5},
 '%Cars': {0: 25, 1: 65, 2: 0, 3: 75},
 'Nr Alarms': {0: 1, 1: 2, 2: 3, 3: 4},
 'Nr Block': {0: 1, 1: 2, 2: 3, 3: 4}})

def build_subplot(df, columns=None):
    if columns is None:
        columns =  df.columns
    # only columns starting with %
    columns = [col for col in columns if col.startswith("%")]

    fig = make_subplots(rows=1, cols=2,
        specs=[
            [{"type": "bar"},{"type": "table"}]
            ]
        )
    fig.update_layout(barmode='stack')

    for column in columns:
        fig.append_trace(
            go.Bar(x=df["City"],
                   y=df[column],
                   name=column),
            row=1,col=1)

    fig.add_trace(
        go.Table(
            header=dict(
                values=df.columns,
                font=dict(size=10),
                align="left"
            ),
            cells=dict(
                values=df.T.values.tolist(),
                align = "left")
        ),
        row=1, col=2
        )


    return fig


build_subplot(df, ['%Something', '%Dogs', 'Nr Block'])

enter image description here

Приложение: Я думаю, что будет лучше, если у вас будет субплот с 1 столбцом и 2 строками, поскольку некоторые детали из таблицы могут быть трудночитаемыми.

0 голосов
/ 22 апреля 2020

понял, что я сделал не так!

Вместо использования plot_.figure_factory's create_table () я использовал plotly.graph_objects Table ()

Мне также пришлось определить тип рисунка, использованного при создании подзаговора. Окончательное решение для создания подзаговора выглядит так:

def build_subplot(df,columns):

    x = df.City.astype('str').unique()
    fig = make_subplots(rows=1, cols=2,
        specs=[
            [{"type": "bar"},{"type": "table"}]
            ]
        )
    fig.update_layout(barmode='stack')

    for column in columns:
        Y=df[column].tolist()
        fig.append_trace(go.Bar(name=column,x=x,y=Y),row=1,col=1)

    fig.add_trace(
        go.Table(
            header=dict(
                values=df.columns,
                font=dict(size=10),
                align="left"
            ),
            cells=dict(
                values=[df[k].tolist() for k in df.columns],
                align = "left")
        ),
        row=1, col=2
        )


    return fig 

Надеюсь, это поможет кому-то еще :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...