File size: 4,205 Bytes
f6be049
 
938a35d
f6be049
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82057dc
 
 
f6be049
 
 
82057dc
f6be049
 
 
 
 
 
 
 
 
 
 
 
 
938a35d
 
f6be049
 
4595ac8
be43693
f6be049
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import streamlit as st
import datetime
import numpy as np

today = datetime.date.today()

def plot(df, n=10):
    import plotly.express as px

    # Order: prev pred, future pred, real
    line_colors = ['tomato', 'steelblue', 'limegreen']

    # Extract the x-axis values (dates) from the dataframe
    x_values = df["date"]

    # Define your colors, labels, and ranges
    colors = ['green', 'yellow', 'orange', 'red', 'purple', 'darkred']
    labels = ['Good', 'Moderate', 'Unhealthy for Some', 'Unhealthy', 'Very Unhealthy', 'Hazardous']
    ranges = [(1, 49), (50, 99), (100, 149), (150, 199), (200, 299), (300, 500)]  # Avoid 0 for log scale

    # Create the Plotly Express line chart for actual pm25
    fig = px.line(
        df.iloc[:-n],  # Exclude the last n points
        x="date", 
        y="pm25", 
        markers=True,
        line_shape='linear'
    )
    fig.update_traces(line=dict(color=line_colors[2]), name='Actual', showlegend=True)

    # Add the predicted pm25 line in two segments
    fig.add_scatter(
        x=df["date"][:-n], 
        y=df["predicted_pm25"][:-n], 
        mode='lines+markers', 
        name='Past prediction', 
        line=dict(color=line_colors[0], width=3), 
        marker=dict(size=10)
    )

    fig.add_scatter(
        x=df["date"][-n:], 
        y=df["predicted_pm25"][-n:], 
        mode='lines+markers', 
        name='Future prediction', 
        line=dict(color=line_colors[1], width=3, dash='dot'), 
        marker=dict(size=10)
    )
    # Add a dotted line connecting past predicted pm25 to future predicted pm25
    fig.add_scatter(
        x=[df["date"].iloc[-n-1], df["date"].iloc[-n]], 
        y=[df["predicted_pm25"].iloc[-n-1], df["predicted_pm25"].iloc[-n]], 
        mode='lines', 
        name='Connecting Line', 
        line=dict(color=line_colors[1], width=3, dash='dot'),
        showlegend=False  # Remove from legend
    )

    # Add background color rectangles using `shapes`
    shapes = []
    for i, (start, end) in enumerate(ranges):
        shapes.append(
            dict(
                type="rect",  # Add a rectangle
                xref="paper",  # Extend the rectangle across the entire x-axis
                yref="y",      # Anchor the rectangle to the y-axis
                x0=0,          # Start from the left (x0 in paper coordinates)
                x1=1,          # End at the right (x1 in paper coordinates)
                y0=start,      # Start of the y-range
                y1=end,        # End of the y-range
                fillcolor=colors[i],  # Background color
                opacity=0.2,          # Transparency level
                layer="below",        # Place behind the data
                line_width=0          # No border
            )
        )

    label_font_size = 26
    ticks_font_size = 20

    # Update the layout and traces for customization
    fig.update_traces(
        marker=dict(size=10),  # Increase marker size
        line=dict(width=3)     # Make the line thicker
    )

    # x range start BEFORE today
    k = 4

    fig.update_layout(
        shapes=shapes,  # Add the background rectangles
        xaxis=dict(
            range=[x_values.iloc[-n-k], x_values.iloc[-1]],  # Dynamically set the range
            title=dict(
                text="Date",  # Set x-axis label
                font=dict(size=label_font_size)  # Increase font size for the x-axis label
            ),
            tickfont=dict(size=ticks_font_size)  # Increase font size for x-axis numbers
        ),
        yaxis=dict(
            title=dict(
                text="log PM2.5",  # Set y-axis label
                font=dict(size=label_font_size)  # Increase font size for the y-axis label
            ),
            type="log",  # Set y-axis to logarithmic scale
            fixedrange=True,  # Disable vertical panning/zooming
            tickfont=dict(size=ticks_font_size),  # Increase font size for y-axis numbers
            range=[1, np.log10(500)]  # Set y-axis range to be positive
        ),
        autosize=True,
        width=2100,
        height=750,
        hoverlabel=dict(
            font_size=20  # Increase hover label font size
        )
    )

    return fig