Search code examples
plotly

Display multiple plots (not subplots) with plotly


I can display a graph for each Region of my country by changing the variable "region" so This is how it looks: enter image description here

I'm trying to make a loop that will create a graph for each region. I tried with subplots but seems to not be the way because I want an individual graph just like this one (with his legend, title, etc) but with subplots I'm getting 1 legend with all the categories and it doesn't look right.

I also tried using region as an argument of my function that displays the chart, but when I do that it opens 17 different windows with their charts, and it does the job exactly how I need it but I would like to display all the graphs in 1 single page. How can I do that?

This is the code:

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

def camasRegion():  
    df = pd.read_csv('https://raw.githubusercontent.com/MinCiencia/Datos-COVID19/master/output/producto52/Camas_UCI.csv')
    region = "Atacama"
    Regiones = df['Region'].drop_duplicates()
    fig = make_subplots(rows=17, cols=1)
    chart = [] 
    for x in Regiones:
        count = 1 #Tried to use index and many other functions to get the position of the element in arrays and dataframe but couldn't do it.
        target_regions = df.query('Region == @x').drop('Region', axis=1).set_index('Serie').T
        for i in target_regions:
            if i != 'Camas base (2019)':  #or you can easily drop it from your dataset
             chart += [fig.add_trace(go.Scatter(x=target_regions.index,y=target_regions[i], name=i, mode='lines' ),row=count, col=1)]
             count += 1   

    fig.update_layout(title={'text':f'Camas UCI por región: ({region})', 'x':.45},
                      template='plotly_white', hovermode='x',
                      showlegend=False,
                      xaxis_title="Días",
                      yaxis_title="Cantidad de camas",
                      height=9000                      
                      )

    fig.add_annotation(
        x = 1, y = -0.1, 
        text = 'Fuente: Datos obtenidos desde el Ministerio de Ciencia:', 
        showarrow = False, xref='paper', yref='paper', 
        xanchor='right', yanchor='auto', xshift=0, yshift=-20
        )
    fig.show()


camasRegion()

Thanks for helping.


Solution

  • To add a legend to each of the subplots, give the legend group a string in group units. They are usually arranged according to each subplot. In your example, you will need to adjust the spacing between the legends because of the large number of graphs. I found the current values through trial and error.

    fig = make_subplots(rows=len(Regiones),
                        cols=1,
                        subplot_titles=Regiones)
    
    for i,r in enumerate(Regiones):
        target_regions = df.query('Region == @r').drop('Region', axis=1).set_index('Serie').T
        for c in target_regions.columns[:3]:
            fig = fig.add_trace(
                go.Scatter(x=target_regions.index,
                           y=target_regions[c],
                           name=c,
                           mode='lines', 
                           legendgroup=str(i),
                           showlegend=True
                          ), row=i+1, col=1)
    
    fig.update_layout(title={'text':f'Camas UCI por región', 'x':.45},
                      template='plotly_white', hovermode='x',
                      showlegend=True,
                      xaxis_title="Días",
                      yaxis_title="Cantidad de camas",
                      legend_tracegroupgap=90,
                      height=2600                      
                      )
    
    fig.add_annotation(x=0.75, y=0.00,
                       text = 'Fuente: Datos obtenidos desde el Ministerio de Ciencia:', 
                       showarrow = False, 
                       xref='paper',
                       yref='paper', 
                       xanchor='right',
                       yanchor='bottom',
                       xshift=0,
                       yshift=-30
                      )   
    
    
    fig.show()
    

    enter image description here