File size: 4,504 Bytes
f6be049
 
938a35d
f6be049
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82057dc
 
4627c46
 
 
 
 
 
 
82057dc
f6be049
 
 
82057dc
f6be049
 
 
 
 
 
 
 
 
 
 
 
 
938a35d
 
f6be049
 
4627c46
 
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
119
120
121
122
123
124
125
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
    # Get the screen dimensions
    screen_width = st.get_option("browser.clientWidth")
    screen_height = st.get_option("browser.clientHeight")

    # Set the width and height to take up nearly the entire screen
    fig_width = screen_width * 0.8
    fig_height = screen_height * 0.65

    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=fig_width,
        height=fig_height,
        hoverlabel=dict(
            font_size=20  # Increase hover label font size
        )
    )

    return fig