Home Forum Statistica con R Aggiungere un grafico fatto con ggplot ad un grafico che ne contiene già altri.

Questo argomento contiene 9 risposte, ha 2 partecipanti, ed è stato aggiornato da Francesco Cabiddu Francesco Cabiddu 3 mesi fa.

Stai vedendo 10 articoli - dal 1 a 10 (di 10 totali)
  • Autore
    Articoli
  • #5790

    pdeninis
    Partecipante

    Buonasera a tutti.

    Attraverso il comando

    par(mfrow = c(1,2))

    è possibile affiancare più grafici, se fatti p. es. con plot().

    Se invece il grafico è prodotto da ggplot, mi accade che, nell’aggiungere il secondo grafico alla finestra aperta, ggplot riscriva su tutta la finestra, sovrascrivendo il precedente già inserito.

    1 È possibile evitare che ciò avvenga?
    2 È possibile anche se ggplot non fa parte del mio codice, ma è richiamato indirettamente da un’altra funzione che gli passa solo alcuni (pochi) predeterminati parametri?

    Paolo

    • Questo argomento è stato modificato 3 mesi, 1 settimana fa da  pdeninis.
    #5823
    Francesco Cabiddu
    Francesco Cabiddu
    Amministratore del forum

    Ciao Paolo,
    puoi utilizzare la funzione riportata in questa pagina per affiancare più plot.
    Se i plot hanno una legenda in comune leggi qui per avere suggerimenti su come procedere.

    Io avevo modificato (molto confusamente andando per prove ed errori essendo sincero) la funzione del secondo link, per poter fare in modo che i grafici potessero condividere non solo la legenda ma anche i nomi degli assi. La funzione modificata è questa:

    
    library(gridExtra)
    library(grid)
    
    grid_arrange_shared_legend <- function(..., nrow = 1,y_title, x_size, y_size,widths1 = 2, widths2=0.2,hjust1=1, x_title, ncol = length(list(...)), position = c("bottom", "right")) {
    
      plots <- list(...)
      position <- match.arg(position)
      g <- ggplotGrob(plots[[1]] + theme(legend.position = position))$grobs
      legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]
      lheight <- sum(legend$height)
      lwidth <- sum(legend$width)
      gl <- lapply(plots, function(x) x + theme(legend.position = "none"))
      gl <- c(gl, nrow = nrow, ncol = ncol)
    
      combined <- switch(position,
                         "bottom" = arrangeGrob(do.call(arrangeGrob, gl),
                                                legend,
                                                ncol = 1,
                                                heights = unit.c(unit(1, "npc") - lheight, lheight)),
                         "right" = arrangeGrob(do.call(arrangeGrob, gl),
                                               legend,
                                               ncol = 2,
                                               widths = c(widths1, widths2),
                                               left=textGrob(y_title, gp=gpar(fontsize=y_size), rot = 90),
                                               bottom=textGrob(x_title, gp=gpar(fontsize=x_size), vjust = 0, hjust = hjust1)))
      grid.newpage()
      grid.draw(combined)
    
    }
    

    La puoi applicare in questo modo:

    
    grid_arrange_shared_legend(plot1, plot2, plot3, position = "right", 
                               x_title = "Nome asse x", y_title = "Nome asse y",
                               x_size = 25, y_size = 25,
                               widths1 = 2, widths2 = 0.5, hjust1 = 1)
    

    Dovrai solo togliere i nomi degli assi dei rispettivi plot perché li imposterai alla fine, usando gli argomenti x_title e y_title di grid_arrange_shared_legend.

    Per quanto riguarda la tua seconda domanda, dovrebbe essere possibile concatenare i grafici anche se il ggplot è costruito indirettamente, poiché l’oggetto grafico che ottieni indirettamente dovrebbe essere sempre un ggplot suppongo

    #5833

    pdeninis
    Partecipante

    Ciao Francesco, speravo che mi rispondessi.

    La tua funzione, se non ho capito male, permette di mettere insieme più grafici fatti con ggplot. Naturalmente ci provo a giocare un po’ e ti dirò come va. In previsione mi tornerà certo utilissima!

    La mia domanda in questo caso era: come si fa ad aggiungere un ggplot ad una finestra

    
    windows(16,12);par(mfrow = c(2,3), oma=c(0,0,2,0))
    

    che contiene già 5 dei 6 grafici che può contenere, ottenuti con funzione base.

    Io inserisco i 5 grafici con plot() e si dispongono correttamente.
    Quando però vado ad aggiungere il sesto con ggplot, gli altri vengono sovrascritti e ggplot occupa tutto lo spazio.

    Chiedevo se esiste un comando dato all’atto di generare il 6° con ggplot che lo faccia comportare come plot(), cioè non gli faccia riscrivere la finestra che trova aperta ma lo faccia allocare nello spazio rimasto libero.

    Usando la tua funzione invece di par() dovrei poter aggiungere anche grafici fatti con plot() vero?

    E se invece assegno il grafico di ggplot ad una variabile (oggetto) c’è modo di aggiungere quello alla finestra aperta con windows() e par()?

    • Questa risposta è stata modificata 3 mesi, 1 settimana fa da  pdeninis.
    #5838
    Francesco Cabiddu
    Francesco Cabiddu
    Amministratore del forum

    Azz scusami non avevo colto bene la domanda. Io non ho mai provato a concatenare base r plots e ggplots, ma questo link sembra utile, vedi se riesci. Poi mi metto a giocarci anche io appena ho tempo quindi se hai difficoltà scrivi che proviamo assieme

    #5856

    pdeninis
    Partecipante

    Caspita! Ma come l’hai trovato?
    Non sai quanto ho cercato.

    Sembra proprio quel che fa per me. Me lo studio e ti dico.

    Grazie!!

    • Questa risposta è stata modificata 3 mesi, 1 settimana fa da  pdeninis.
    #5859

    pdeninis
    Partecipante

    Con il comando viewport() sembra possibile inserire il grafico in una porzione da te indicata, con dimensioni definibili.

    Però i valori incidono soltanto sul grafico, lasciando inalterata la dimensione dei caratteri.

    A questo punto sarebbe decisivo poter spostare la legenda del grafico ggplot in basso.

    Il codice che avevi fatto tu era questo:

    
    P<-ggplot(DF2, aes(x=fct_reorder(Method,desc(Ord)), y=Estimate, shape=Differences)) +
        geom_point(position=position_dodge(width=0.50),aes(shape=Differences), size=1.5) +
        geom_errorbar(aes(ymin = lwr, ymax=upr), 
                      width=.2,                    
                      position=position_dodge(.5)) +
        theme(panel.background = element_rect(fill = "white", 
                                              colour = "grey50"),
              panel.grid.major = element_blank(), 
              panel.grid.minor = element_blank(),
              legend.key = element_rect(fill = "transparent", colour = "transparent")) +
        labs(title = "GT increase: 95% CI of Differences") +
        xlab("") +
        geom_hline(yintercept = 0, linetype="dotted") +
        coord_flip() +
        scale_y_continuous(limits = c(-1,0.6)) # ho aggiunto questo per impostare manualmente i limiti dell'asse x ma puoi toglierlo se vuoi
    
    windows(16,12);par(mfrow = c(2,3), oma=c(0,0,2,0))
    ## .....     5 grafici inseriti
    ### Codice per definire la vista ####
    vp.BottomRight <- viewport(height=unit(.4, "npc"), width=unit(0.4, "npc"), 
                               just=c("left","top"), 
                               y=0.45, x=0.64)
    print(P, vp=vp.BottomRight) 
    
    

    Si può spostare la legenda sotto il grafico, naturalmente comprimendolo?

    • Questa risposta è stata modificata 3 mesi, 1 settimana fa da  pdeninis.
    • Questa risposta è stata modificata 3 mesi, 1 settimana fa da  pdeninis.
    • Questa risposta è stata modificata 3 mesi, 1 settimana fa da  pdeninis.
    #5864
    Francesco Cabiddu
    Francesco Cabiddu
    Amministratore del forum

    Ok son contento che stai riuscendo. Per spostare la legenda sotto penso che basti aggiungere dentro theme() l’argomento legend.position="bottom". Quindi il tuo ggplot diventa:

    
    P<-ggplot(DF2, aes(x=fct_reorder(Method,desc(Ord)), y=Estimate, shape=Differences)) +
        geom_point(position=position_dodge(width=0.50),aes(shape=Differences), size=1.5) +
        geom_errorbar(aes(ymin = lwr, ymax=upr), 
                      width=.2,                    
                      position=position_dodge(.5)) +
        theme(panel.background = element_rect(fill = "white", 
                                              colour = "grey50"),
              panel.grid.major = element_blank(), 
              panel.grid.minor = element_blank(),
              legend.key = element_rect(fill = "transparent", colour = "transparent"),
              legend.position="bottom") +
        labs(title = "GT increase: 95% CI of Differences") +
        xlab("") +
        geom_hline(yintercept = 0, linetype="dotted") +
        coord_flip() +
        scale_y_continuous(limits = c(-1,0.6)) # ho aggiunto questo per impostare manualmente i limiti dell'asse x ma puoi toglierlo se vuoi
    

    Ps Stackoverflow ha spesso le risposte a molte domande quando provi a utilizzare diverse parole chiave. Per trovare il link riportato sopra ho scritto nella funzione di ricerca “combine plots and ggplots R”.

    #5875

    pdeninis
    Partecipante

    Ps Stackoverflow ha spesso le risposte a molte domande quando provi a utilizzare diverse parole chiave. Per trovare il link riportato sopra ho scritto nella funzione di ricerca “combine plots and ggplots R”.

    Evidentemente devo affinare l’individuazione delle parole chiave…

    Provo e ti aggiorno. Grazie mille!!

    #5876

    pdeninis
    Partecipante

    Funziona. Però nello spostare in basso la legenda mette le tre chiavi relative alle tre differenze non più in una sola colonna in tre righe ma in 3 colonne su una sola riga, costringendomi ad eliminare il titolo della legenda ed a rimpicciolire il carattere per non sforare.

    Anche qui bisognerebbe avere piena comprensione della struttura del funzionamento di ggplot ed in particolare del comando guide_legend() che pare non faccio quello che avevo capito dovrebbe fare…

    Inoltre devo rimpicciolire il carattere del testo relativo all’asse y (x con il coord_flip).

    • Questa risposta è stata modificata 3 mesi, 1 settimana fa da  pdeninis.
    #5902
    Francesco Cabiddu
    Francesco Cabiddu
    Amministratore del forum

    Ciao Paolo,
    scusa per il ritardo.
    Puoi aggiungere questo pezzo al grafico per modificare la disposizione dei livelli della legenda:

    
    plot + 
        guides(shape=guide_legend(nrow=3,byrow=TRUE))
    

    E se volessi il titolo della legenda in alto:

    
    
    plot + 
        guides(shape=guide_legend(nrow=3,byrow=TRUE,title.position="top"))
    
    

    Per diminuire il carattere del titolo o del testo di un asse puoi aggiungere dentro theme:

    
    theme(axis.title.x = element_text(size = 20),
          axis.text.x = element_text(size = 20))
    
Stai vedendo 10 articoli - dal 1 a 10 (di 10 totali)

Devi essere loggato per rispondere a questa discussione.