Black Lives Matter. Please consider donating to Black Girls Code today.

Plotly axis problems

i have a log file and its looks like this,

2020-04-23T15:02:01.329095-05:00, 45
2020-04-23T15:02:16.318611-05:00, 46

when i run plotly the values 45,46 show up as 4500,4600, but only when i use,

yaxis_tickformat=’%’,

why is this can someone help me out here?
thanks

Hi @notsolowki,

Welcome to forum!!! Plotly follows the d3.js rules for tickformatting. if you are printing
help(go.layout.YAxis.tickformat) you’ll find a link to d3.js

https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format, where it is explained how '%' works:

percentage ("%") - like fixed, but multiply by 100 and suffix with "%".

Hence to get displayed the right information in the trace definition where you pass the y-values to be displayed as percentage just divide those values by 100.
If you read the log file as a pandas data frame, then define
y = df['percent'].values/100

i have tried your solution but i cant seem to make it work. i just end up with the right range in the humidity y axis but no data on the plot ‘that i cant see anyways’

import dash
from dash.dependencies import Output, Input, State
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go
import csv
import itertools
import datetime as dt
import attr


@attr.s(frozen=True)
class Plot:
    xs = attr.ib()
    ys = attr.ib()



def _humidity():
    with open("z:/Humidity Log.txt", "r") as csvfile:
        reader = csv.reader(csvfile)
        plots = itertools.islice(reader, None, None, 1)
        return Plot(
            *zip(*((dt.datetime.fromisoformat(x), float(y)) for x, y, *_ in plots))

        )


def _temp():
    with open("Z:/Temp Log.txt", "r") as csvfile:
        reader = csv.reader(csvfile)
        plots = itertools.islice(reader, None, None, 1)
        return Plot(
            *zip(*((dt.datetime.fromisoformat(x), float(y)) for x, y, *_ in plots))
        )

def _auxInput():
    with open("Z:/Temp Log.txt", "r") as csvfile:
        reader = csv.reader(csvfile)
        plots = itertools.islice(reader, None, None, 20)
        return Plot(
            *zip(*((dt.datetime.fromisoformat(x), float(y)) for x, y, *_ in plots))
        )

def auxinput(n):
    aux = _auxInput()
    return {
        "data": [
            plotly.graph_objs.Scatter(
                x=list(aux.xs),
                y=list(aux.ys),
                line={"color": "#008f13"},
                name="A/C Run-time",
                mode="lines+markers",
            ),
        ],
        "layout": go.Layout(
            uirevision="null",
            height=500,
            plot_bgcolor="rgb(219, 219, 219)",
            xaxis={
                "type": "date",
                "range": [min(aux.xs), max(aux.xs)],
            },

            yaxis_tickwidth=2,
            xaxis_tickangle=45,
            yaxis_linewidth=1,
            xaxis_linewidth=1,
            xaxis_tickformatstops=[
                dict(dtickrange=[None, 1000], value="%H:%M:%S.%L ms"),
                dict(dtickrange=[1000, 60000], value="%H:%M:%S s"),
                dict(dtickrange=[60000, 3600000], value="%H:%M m"),
                dict(dtickrange=[3600000, 86400000], value="%H:%M h"),
                dict(dtickrange=[86400000, 604800000], value="%e. %b d"),
                dict(dtickrange=[604800000, "M1"], value="%e. %b w"),
                dict(dtickrange=["M1", "M12"], value="%b '%y M"),
                dict(dtickrange=["M12", None], value="%Y Y")
            ],
            yaxis={"title": "A/C Run-time",
                   'autorange': True,
                   "range": [min(aux.ys), max(aux.ys)]},
        ),
    }

def temperature(n):
    temp = _temp()
    return {
        "data": [
            plotly.graph_objs.Scatter(
                x=list(temp.xs),
                y=list(temp.ys),
                line={"color": "#f51000"},
                name="Temperature",
                mode="lines+markers",
                #yaxis_tickformat='%',
    ),
        ],
        "layout": go.Layout(
            uirevision='any',
            height=500,
            plot_bgcolor="rgb(219, 219, 219)",
            xaxis={
                "type": "date",
                "range": [min(temp.xs), max(temp.xs)],
            },
            yaxis_tickwidth=2,
            xaxis_tickangle=45,
            yaxis_linewidth=1,
            xaxis_linewidth=1,
            xaxis_tickformatstops=[
                dict(dtickrange=[None, 1000], value="%H:%M:%S.%L ms"),
                dict(dtickrange=[1000, 60000], value="%H:%M:%S s"),
                dict(dtickrange=[60000, 3600000], value="%H:%M m"),
                dict(dtickrange=[3600000, 86400000], value="%H:%M h"),
                dict(dtickrange=[86400000, 604800000], value="%e. %b d"),
                dict(dtickrange=[604800000, "M1"], value="%e. %b w"),
                dict(dtickrange=["M1", "M12"], value="%b '%y M"),
                dict(dtickrange=["M12", None], value="%Y Y")
            ],
            yaxis={"title": "Temperature",'fixedrange': True,'autorange': True,"range": [min(temp.ys), max(temp.ys)]},
        ),
    }

def humidity(n):
    humidity = _humidity()

    return {
        "data": [
            plotly.graph_objs.Scatter(
                x=list(humidity.xs),
                y=list(humidity.ys),


                line={"color": "#0539f7"},
                name="Humidity",
                mode="lines+markers",
            ),
        ],
        "layout": go.Layout(
            uirevision="null",
            height=500,
            plot_bgcolor="rgb(219, 219, 219)",
            yaxis_tickwidth = 2,
            xaxis_tickangle = 45,
            yaxis_linewidth=1,
            xaxis_linewidth=1,
            yaxis_tickformat='%',

            xaxis={"type": "date","range": [min(humidity.xs), max(humidity.xs)],},
            yaxis={"title": "Humidity", 'fixedrange': True,   "range": [min(humidity.ys)/100, max(humidity.ys)/100]},
        ),
    }

app = dash.Dash(__name__)
app.title = 'Temp/Humidity Graph'
app.layout = html.Div([
        dcc.Graph(
            id="live-temperature",
            animate=False,
            config={"displaylogo": False,
                    "scrollZoom": True,
                    "modeBarButtonsToRemove": ['lasso2d',
                                               'toggleSpikelines']},
            figure=temperature(0),
        ),
        dcc.Graph(
            id="live-humidity",
            animate=False,

            config={"displaylogo": False,
                    "scrollZoom": True,
                    "modeBarButtonsToRemove": ['lasso2d',
                                                'toggleSpikelines']},
            figure=humidity(0),
    ),
        dcc.Graph(
            id="live-auxInput",
            animate=False,
            config={"displaylogo": False,
                    "scrollZoom": True,
                    "modeBarButtonsToRemove": ['lasso2d',
                                           'toggleSpikelines']},
            figure=auxinput(0),
    ),
        dcc.Interval(id="graph-update", interval=1 * 5000),
    ]
)

@app.callback(
    Output("live-temperature", "figure"),
    [Input("graph-update", "n_intervals")],
)

def update_graph_scatter_temp(n):
    return temperature(n)
@app.callback(
    Output("live-humidity", "figure"),
    [Input("graph-update", "n_intervals")],

)

def update_graph_scatter_humidity(n):
    return humidity(n)

@app.callback(
    Output("live-auxInput", "figure"),
    [Input("graph-update", "n_intervals")],
)

def update_graph_scatter_aux(n):
    return auxinput(n)

if __name__ == "__main__":
    app.run_server(host="0.0.0.0", port=8051, debug=False)

note the /100 after humidity.ys

@notsolowki

Please don’t paste hereyour dash code. Just define a go.Figure, first, to check how it works. Without data I cannot run to see what is happening. See also: https://plotly.com/python/tick-formatting/#using-tickformat-attribute.

what do you mean? would you rather have incomplete code? oh im sorry i use dash. my question with plotly still stood. there is plotly in that code.

Yes you were correct about the division thankyou.

the solution was zip(((dt.datetime.fromisoformat(x), float(y)/100) for x, y, *_ in plots))

    )
import dash
from dash.dependencies import Output, Input, State
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go
import csv
import itertools
import datetime as dt
import attr
import copy


@attr.s(frozen=True)
class Plot:
    xs = attr.ib()
    ys = attr.ib()


def _humidity():
    with open("z:/Humidity Log.txt", "r") as csvfile:
        reader = csv.reader(csvfile)
        plots = itertools.islice(reader, None, None, 1)
        return Plot(
            *zip(*((dt.datetime.fromisoformat(x), float(y)/100) for x, y, *_ in plots))
        )


def _temp():
    with open("Z:/Temp Log.txt", "r") as csvfile:
        reader = csv.reader(csvfile)
        plots = itertools.islice(reader, None, None, 1)
        return Plot(
            *zip(*((dt.datetime.fromisoformat(x), float(y)) for x, y, *_ in plots))
        )


def _auxInput():
    with open("Z:/Temp Log.txt", "r") as csvfile:
        reader = csv.reader(csvfile)
        plots = itertools.islice(reader, None, None, 1)
        return Plot(
            *zip(*((dt.datetime.fromisoformat(x), float(y)) for x, y, *_ in plots))
        )


def auxinput(n):
    aux = _auxInput()
    return {
        "data": [
            plotly.graph_objs.Scatter(
                x=list(aux.xs),
                y=list(aux.ys),
                line={"color": "#008f13"},
                name="A/C Run-time",
                mode="lines+markers",
            ),
        ],
        "layout": go.Layout(
            uirevision="null",
            height=500,
            plot_bgcolor="rgb(219, 219, 219)",
            xaxis={"type": "date", "range": [min(aux.xs), max(aux.xs)],},
            yaxis_tickwidth=2,
            xaxis_tickangle=45,
            yaxis_linewidth=1,
            xaxis_linewidth=1,
            xaxis_tickformatstops=[
                dict(dtickrange=[None, 1000], value="%H:%M:%S.%L ms"),
                dict(dtickrange=[1000, 60000], value="%H:%M:%S s"),
                dict(dtickrange=[60000, 3600000], value="%H:%M m"),
                dict(dtickrange=[3600000, 86400000], value="%H:%M h"),
                dict(dtickrange=[86400000, 604800000], value="%e. %b d"),
                dict(dtickrange=[604800000, "M1"], value="%e. %b w"),
                dict(dtickrange=["M1", "M12"], value="%b '%y M"),
                dict(dtickrange=["M12", None], value="%Y Y"),
            ],
            yaxis={
                "title": "A/C Run-time",
                "fixedrange": True,
                "autorange": True,
                "range": [min(aux.ys), max(aux.ys)],
            },
        ),
    }


def temperature(n):
    temp = _temp()
    return {
        "data": [
            plotly.graph_objs.Scatter(
                x=list(temp.xs),
                y=list(temp.ys),
                line={"color": "#f51000"},
                name="Temperature",
                mode="lines+markers",
            ),
        ],
        "layout": go.Layout(
            uirevision="any",
            height=500,
            plot_bgcolor="rgb(219, 219, 219)",
            xaxis={"type": "date", "range": [min(temp.xs), max(temp.xs)],},
            yaxis_tickwidth=2,
            xaxis_tickangle=45,
            yaxis_linewidth=1,
            xaxis_linewidth=1,
            xaxis_tickformatstops=[
                dict(dtickrange=[None, 1000], value="%H:%M:%S.%L ms"),
                dict(dtickrange=[1000, 60000], value="%H:%M:%S s"),
                dict(dtickrange=[60000, 3600000], value="%H:%M m"),
                dict(dtickrange=[3600000, 86400000], value="%H:%M h"),
                dict(dtickrange=[86400000, 604800000], value="%e. %b d"),
                dict(dtickrange=[604800000, "M1"], value="%e. %b w"),
                dict(dtickrange=["M1", "M12"], value="%b '%y M"),
                dict(dtickrange=["M12", None], value="%Y Y"),
            ],
            yaxis={
                "title": "Temperature",
                "fixedrange": True,
                "autorange": True,
                "range": [min(temp.ys), max(temp.ys)],
            },
        ),
    }


def humidity(n):
    humidity = _humidity()
    return {
        "data": [
            plotly.graph_objs.Scatter(
                x=list(humidity.xs),
                y=list(humidity.ys),
                line={"color": "#0539f7"},
                name="Humidity",
                mode="lines+markers",
            ),
        ],
        "layout": go.Layout(
            uirevision="null",
            height=500,
            plot_bgcolor="rgb(219, 219, 219)",
            yaxis_tickwidth=2,
            #yaxis_tickmode='%',
            yaxis_tickformat='%',
            xaxis_tickangle=45,
            yaxis_linewidth=1,
            xaxis_linewidth=1,
            xaxis_tickformatstops=[
                dict(dtickrange=[None, 1000], value="%H:%M:%S.%L ms"),
                dict(dtickrange=[1000, 60000], value="%H:%M:%S s"),
                dict(dtickrange=[60000, 3600000], value="%H:%M m"),
                dict(dtickrange=[3600000, 86400000], value="%H:%M h"),
                dict(dtickrange=[86400000, 604800000], value="%e. %b d"),
                dict(dtickrange=[604800000, "M1"], value="%e. %b w"),
                dict(dtickrange=["M1", "M12"], value="%b '%y M"),
                dict(dtickrange=["M12", None], value="%Y Y"),
            ],
            xaxis={"type": "date", "range": [min(humidity.xs), max(humidity.xs)],},
            yaxis={
                "title": "Humidity",
                "fixedrange": True,
                "range": [min(humidity.ys), max(humidity.ys)],
            },
        ),
    }


app = dash.Dash(__name__)
app.title = "Temp/Humidity Graph"
app.layout = html.Div(
    [
        dcc.RadioItems(
            id="lock-zoom",
            options=[{"label": i, "value": i} for i in ["Lock View", "Refresh View"]],
            value="Lock View",
        ),
        dcc.Graph(
            id="live-temperature",
            animate=False,
            config={
                "displaylogo": False,
                "scrollZoom": True,
                "modeBarButtonsToRemove": ["lasso2d", "toggleSpikelines"],
            },
            figure=temperature(0),
        ),
        dcc.Graph(
            id="live-humidity",
            animate=False,
            config={
                "displaylogo": False,
                "scrollZoom": True,
                "modeBarButtonsToRemove": ["lasso2d", "toggleSpikelines"],
            },
            figure=humidity(0),
        ),
        dcc.Graph(
            id="live-auxInput",
            animate=False,
            config={
                "displaylogo": False,
                "scrollZoom": True,
                "modeBarButtonsToRemove": ["lasso2d", "toggleSpikelines"],
            },
            figure=auxinput(0),
        ),
        dcc.Interval(id="graph-update", interval=1 * 10000),
    ]
)


@app.callback(
    Output("live-temperature", "figure"),
    [Input("graph-update", "n_intervals"),
     Input("lock-zoom", "value")],
    [State("live-temperature", "relayoutData")],
)
def update_graph(value, lock_zoom, relayout_data):
    new_figure = copy.deepcopy(temperature('n'))
    new_figure["layout"]

    # relayout_data contains data on the zoom and range actions
    #print(relayout_data)
    if relayout_data and lock_zoom == "Lock View":
        if "xaxis.range[0]" in relayout_data:
            new_figure["layout"]["xaxis"]["range"] = [
                relayout_data["xaxis.range[0]"],
                relayout_data["xaxis.range[1]"],
            ]
        if "yaxis.range[0]" in relayout_data:
            new_figure["layout"]["yaxis"]["range"] = [
                relayout_data["yaxis.range[0]"],
                relayout_data["yaxis.range[1]"],
            ]
    return new_figure

@app.callback(
    Output("live-humidity", "figure"),
    [Input("graph-update", "n_intervals"),
     Input("lock-zoom", "value")],
    [State("live-humidity", "relayoutData")],
)
def update_graph(value, lock_zoom, relayout_data):
    new_figure = copy.deepcopy(humidity('n'))
    new_figure["layout"]

    # relayout_data contains data on the zoom and range actions
    #print(relayout_data)
    if relayout_data and lock_zoom == "Lock View":
        if "xaxis.range[0]" in relayout_data:
            new_figure["layout"]["xaxis"]["range"] = [
                relayout_data["xaxis.range[0]"],
                relayout_data["xaxis.range[1]"],
            ]
        if "yaxis.range[0]" in relayout_data:
            new_figure["layout"]["yaxis"]["range"] = [
                relayout_data["yaxis.range[0]"],
                relayout_data["yaxis.range[1]"],
            ]
    return new_figure



@app.callback(
    Output("live-auxInput", "figure"),
    [Input("graph-update", "n_intervals"),
     Input("lock-zoom", "value")],
    [State("live-auxInput", "relayoutData")],
)
def update_graph(value, lock_zoom, relayout_data):
    new_figure = copy.deepcopy(auxinput('n'))
    new_figure["layout"]

    # relayout_data contains data on the zoom and range actions
    #print(relayout_data)
    if relayout_data and lock_zoom == "Lock View":
        if "xaxis.range[0]" in relayout_data:
            new_figure["layout"]["xaxis"]["range"] = [
                relayout_data["xaxis.range[0]"],
                relayout_data["xaxis.range[1]"],
            ]
        if "yaxis.range[0]" in relayout_data:
            new_figure["layout"]["yaxis"]["range"] = [
                relayout_data["yaxis.range[0]"],
                relayout_data["yaxis.range[1]"],
            ]
    return new_figure




if __name__ == "__main__":
    app.run_server(host="0.0.0.0", port=8051, debug=False)

@notsolowki

If each user posts here his entire project, the person who is answering should devote long time daily to understand the logic of hundreds or thousands of lines of code. The questions related to an issue must be illustrated by a minimal code and some data in order to be able to run and detect the bug. The same rule is on SO, too.

In the first post I gave you the answer and in the second I posted a link to a tutorial. You only had to adapt your code such that to define data in a form that ensures that the percentage is correctly displayed. Finally you succeeded, but instead of being thankful, you were ironic :frowning:

no i said thankyou and was thankful. i was just stating that you cant run the code if its not complete. for example, if i remove dash from the code it will not run period