Saltar al contenido

¿Cómo trazar anomalías usando dos colores en un solo gráfico con pgfplot?

Ya no necesitas investigar más por internet ya que has llegado al sitio indicado, tenemos la respuesta que quieres encontrar pero sin complicaciones.

Solución:

Desafortunadamente, no puede simplemente usar el fillbetween biblioteca de PGFPlots para el primer ejemplo, porque en los datos proporcionados hay valores que son iguales a 0, que también es el valor en el que desea “dividir” los datos en una parte “superior” y una “inferior” que deben manejarse por separado . Pero eso confunde al intersection Biblioteca. Para evitar esto, debe desplazar la línea horizontal (donde se deben dividir los datos) o debe realizar un trabajo “manual” para obtener el resultado deseado.

El siguiente código produce dos ejemplos. El primero es un enfoque más “automatizado” que utiliza el pequeño truco para desplazar la línea horizontal un poco por debajo de cero para evitar el problema mencionado anteriormente, pero por supuesto, cuando mires de cerca, verás que la línea está desplazada. Aquí muestro ambas, es decir, cómo se pueden dibujar las dos partes en diferentes colores y cómo rellenar las áreas en las partes correspondientes. Ambos usan el postaction y decoration características en combinación con el soft clip característica.

El segundo enfoque da como resultado la solución deseada en aras de un poco más de trabajo “manual”. Allí uso el intersection segments característica de la fillbetween biblioteca para establecer manualmente la ruta “inferior” y “superior” del gráfico, respectivamente, en comparación con la línea horizontal donde se dividen los datos.

Para obtener más detalles, consulte los comentarios en el código.

documentclass[border=2mm]standalone
usepackagepgfplots
    usetikzlibrary
        pgfplots.fillbetween,
    
    pgfplotsset
        compat=1.11,
        %
        % define a style which can be used for both plots
        my axis style/.style=
            xmin=1950,
            xmax=2015,
            enlarge x limits=abs=5,
            ymin=-2.5,
            ymax=2.5,
            minor tick num=1,
            ylabel=$Delta T$ $/$ K,
            % remove the `1000 sep'
            xticklabel style=
                /pgf/number format/1000 sep=,
            ,
            line join=bevel,
        ,
    
% missing value for the year 1978
% added a zero in the last column (NDJ)
beginfilecontents*data.dat
    year DJF JFM FMA MAM AMJ MJJ JJA JAS ASO SON OND NDJ
    1950 -1.4 -1.2 -1.1 -1.2 -1.1 -0.9 -0.6 -0.6 -0.5 -0.6 -0.7 -0.8
    1951 -0.8 -0.6 -0.2 0.2 0.2 0.4 0.5 0.7 0.8 0.9 0.7 0.6
    1952 0.5 0.4 0.4 0.4 0.4 0.2 0 0.1 0.2 0.2 0.2 0.3
    1953 0.5 0.6 0.7 0.7 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.7
    1954 0.7 0.4 0 -0.4 -0.5 -0.5 -0.5 -0.7 -0.7 -0.6 -0.5 -0.5
    1955 -0.6 -0.6 -0.7 -0.7 -0.7 -0.6 -0.6 -0.6 -1.0 -1.4 -1.6 -1.4
    1956 -0.9 -0.6 -0.6 -0.5 -0.5 -0.4 -0.5 -0.5 -0.4 -0.4 -0.5 -0.4
    1957 -0.3 0 0.3 0.6 0.7 0.9 1.0 1.2 1.1 1.2 1.3 1.6
    1958 1.7 1.5 1.2 0.8 0.7 0.6 0.5 0.4 0.4 0.5 0.6 0.6
    1959 0.6 0.5 0.4 0.2 0.1 -0.2 -0.3 -0.3 -0.1 -0.1 -0.1 -0.1
    1960 -0.1 -0.2 -0.1 0 -0.1 -0.2 0 0.1 0.2 0.1 0 0
    1961 0 0 -0.1 0 0.1 0.2 0.1 -0.1 -0.3 -0.3 -0.2 -0.2
    1962 -0.2 -0.2 -0.2 -0.3 -0.3 -0.2 -0.1 -0.2 -0.2 -0.3 -0.3 -0.4
    1963 -0.4 -0.2 0.1  0.2 0.2 0.4 0.7 1.0 1.1 1.2 1.2 1.1
    1964 1.0 0.6 0.1 -0.3 -0.6 -0.6 -0.7 -0.7 -0.8 -0.8 -0.8 -0.8
    1965 -0.5 -0.3 -0.1 0.1 0.4 0.7 1.0 1.3 1.6 1.7 1.8 1.5
    1966 1.3 1.0 0.9 0.6 0.3 0.2 0.2 0.1 0 -0.1 -0.1 -0.3
    1967 -0.4 -0.5 -0.5 -0.5 -0.2 0 0 -0.2 -0.3 -0.4 -0.4 -0.5
    1968 -0.7 -0.8 -0.7 -0.5 -0.1 0.2 0.5 0.4 0.3 0.4 0.6 0.8
    1969 0.9 1.0 0.9 0.7 0.6 0.5 0.4 0.5 0.8 0.8 0.8 0.7
    1970 0.6 0.4 0.4 0.3 0.1 -0.3 -0.6 -0.8 -0.8 -0.8 -0.9 -1.2
    1971 -1.3 -1.3 -1.1 -0.9 -0.8 -0.7 -0.8 -0.7 -0.8 -0.8 -0.9 -0.8
    1972 -0.7 -0.4 0 0.3 0.6 0.8 1.1 1.3 1.5 1.8 2.0 1.9
    1973 1.7 1.2 0.6 0 -0.4 -0.8 -1.0 -1.2 -1.4 -1.7 -1.9 -1.9
    1974 -1.7 -1.5 -1.2 -1.0 -0.9 -0.8 -0.6 -0.4 -0.4 -0.6 -0.7 -0.6
    1975 -0.5 -0.5 -0.6 -0.6 -0.7 -0.8 -1.0 -1.1 -1.3 -1.4 -1.5 -1.6
    1976 -1.5 -1.1 -0.7 -0.4 -0.3 -0.1 0.1 0.3 0.5 0.7 0.8 0.8
    1977 0.7 0.6 0.4 0.3 0.3 0.4 0.4 0.4 0.5 0.6 0.8 0.8
    1978 0.7 0.4 0.1 -0.2 -0.3 -0.3 -0.4 -0.4 -0.4 -0.3 -0.10 0
    1979 0 0.1 0.2 0.3 0.3 0.1 0.1 0.2 0.3 0.5 0.5 0.6
    1980 0.6 0.5 0.3 0.4 0.5 0.5 0.3 0.2 0 0.1 0.1 0
    1981 -0.2 -0.4 -0.4 -0.3 -0.2 -0.3 -0.3 -0.3 -0.2 -0.1 -0.1 0
    1982 0 0.1 0.2 0.5 0.6 0.7 0.8 1.0 1.5 1.9 2.1 2.1
    1983 2.1 1.8 1.5 1.2 1.0 0.7 0.3 0 -0.3 -0.6 -0.8 -0.8
    1984 -0.5 -0.3 -0.3 -0.4 -0.4 -0.4 -0.3 -0.2 -0.3 -0.6 -0.9 -1.1
    1985 -0.9 -0.7 -0.7 -0.7 -0.7 -0.6 -0.4 -0.4 -0.4 -0.3 -0.2 -0.3
    1986 -0.4 -0.4 -0.3 -0.2 -0.1 0 0.2 0.4 0.7 0.9 1.0 1.1
    1987 1.1 1.2 1.1 1.0 0.9 1.1 1.4 1.6 1.6 1.4 1.2 1.1
    1988 0.8 0.5 0.1 -0.3 -0.8 -1.2 -1.2 -1.1 -1.2 -1.4 -1.7 -1.8
    1989 -1.6 -1.4 -1.1 -0.9 -0.6 -0.4 -0.3 -0.3 -0.3 -0.3 -0.2 -0.1
    1990 0.1 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.4 0.3 0.4 0.4
    1991 0.4 0.3 0.2 0.2 0.4 0.6 0.7 0.7 0.7 0.8 1.2 1.4
    1992 1.6 1.5 1.4 1.2 1.0 0.8 0.5 0.2 0 -0.1 -0.1 0
    1993 0.2 0.3 0.5 0.7 0.8 0.6 0.3 0.2 0.2 0.2 0.1 0.1
    1994 0.1 0.1 0.2 0.3 0.4 0.4 0.4 0.4 0.4 0.6 0.9 1.0
    1995 0.9 0.7 0.5 0.3 0.2 0 -0.2 -0.5 -0.7 -0.9 -1.0 -0.9
    1996 -0.9 -0.7 -0.6 -0.4 -0.2 -0.2 -0.2 -0.3 -0.3 -0.4 -0.4 -0.5
    1997 -0.5 -0.4 -0.2 0.1 0.6 1.0 1.4 1.7 2.0 2.2 2.3 2.3
    1998 2.1 1.8 1.4 1.0 0.5 -0.1 -0.7 -1.0 -1.2 -1.2 -1.3 -1.4
    1999 -1.4 -1.2 -1.0 -0.9 -0.9 -1.0 -1.0 -1.0 -1.1 -1.2 -1.4 -1.6
    2000 -1.6 -1.4 -1.1 -0.9 -0.7 -0.7 -0.6 -0.5 -0.6 -0.7 -0.8 -0.8
    2001 -0.7 -0.6 -0.5 -0.3 -0.2 -0.1 0 -0.1 -0.1 -0.2 -0.3 -0.3
    2002 -0.2 -0.1 0.1 0.2 0.4 0.7 0.8 0.9 1.0 1.2 1.3 1.1
    2003 0.9 0.6 0.4 0 -0.2 -0.1 0.1 0.2 0.3 0.4 0.4 0.4
    2004 0.3 0.2 0.1 0.1 0.2 0.3 0.5 0.7 0.7 0.7 0.7 0.7
    2005 0.6 0.6 0.5 0.5 0.4 0.2 0.1 0 0 -0.1 -0.4 -0.7
    2006 -0.7 -0.6 -0.4 -0.2 0.0 0.1 0.2 0.3 0.5 0.8 0.9 1.0
    2007 0.7 0.3 0 -0.1 -0.2 -0.2 -0.3 -0.6 -0.8 -1.1 -1.2 -1.3
    2008 -1.4 -1.3 -1.1 -0.9 -0.7 -0.5 -0.3 -0.2 -0.2 -0.3 -0.5 -0.7
    2009 -0.8 -0.7 -0.4 -0.1 0.2 0.4 0.5 0.6 0.7 1.0 1.2 1.3
    2010 1.3 1.1 0.8 0.5 0 -0.4 -0.8 -1.1 -1.3 -1.4 -1.3 -1.4
    2011 -1.3 -1.1 -0.8 -0.6 -0.3 -0.2 -0.3 -0.5 -0.7 -0.9 -0.9 -0.8
    2012 -0.7 -0.6 -0.5 -0.4 -0.3 -0.1 0.1 0.3 0.4 0.4 0.2 -0.2
    2013 -0.4 -0.5 -0.3 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 -0.2 -0.3
    2014 -0.5 -0.6 -0.4 -0.2 0 0 0 0 0.2 0.4 0.6 0.6
    2015 0.5 0.4 0.5 0.7 0.9 1.0 1.2 1.5 1.8 2.1 2.2 2.3
endfilecontents*
begindocument
        pgfplotstablereaddata.datdata
    % first, more automated approach
    % which gives almost the desired result
    begintikzpicture
        beginaxis[
            my axis style,
        ]
            % define a y value where to clip
            % (this is needed because at exactly 0 you will get an
            %  undesired result; give it a try to see what is happening)
            pgfmathsetmacroyclip-0.03

            % define a horizontal line where the values should be split
            % into an upper and a lower part
            path [
                draw=black,
                name path=split path,
            ]
                (pgfkeysvalueof/pgfplots/xmin,yclip)
                -- (pgfkeysvalueof/pgfplots/xmax,yclip);

            % draw the plot in blue
            addplot [
                blue,
                name path=curve,
                % using `postaction' and `decorate' we draw the plot in red
                % but clip it only to the "upper" part of using `soft clip'
                postaction=
                    decorate,
                    red,
                    thin,
                ,
                decoration=
                    soft clip,
                    soft clip path=
                        (pgfkeysvalueof/pgfplots/xmin,yclip)
                        rectangle
                        (pgfkeysvalueof/pgfplots/xmax,pgfkeysvalueof/pgfplots/ymax)
                    ,
                ,
            ] table [x=year,y=DJF] data;

            % with the clipped `curve' path we can now also fill the area
            % (to do the same for the lower part you need to add another
            %  `addplot' now clipping the "lower" part and then just add
            %  another `addplot fill between')
            addplot [red!25]  fill between [of=split path and curve];
        endaxis
    endtikzpicture

    % second, more manual approach
    % giving the wanted solution
    begintikzpicture
        beginaxis[
            my axis style,
        ]
            % what column should be printed
            newcommand*ColNameDJF

            % define a horizontal line where the values should be split
            % into an upper and a lower part
            path [
%                draw=black,
                name path=origin,
            ]
                (pgfkeysvalueof/pgfplots/xmin,0)
                -- (pgfkeysvalueof/pgfplots/xmax,0);

            % just plot one line
            addplot [
                name path=curve,
            ] table [x=year,y=ColName] data;

            % compute + label the upper segment (but do not draw it):
            path [
                name path=upper,
%                draw=red,
%                thick,
                intersection segments=
                    of=origin and curve,
                    sequence=%
                        L1 -- R2 -- L3 -- R4 -- L5
                        -- L6 -- R7 -- L8 -- R9 -- L10
                        -- R11 -- L12 -- R13 -- L14 -- R15
                        -- R16 -- L17 -- R18 -- L19 -- R20
                        -- L21 -- R22 -- L23 -- R24 -- L25
                        -- R26 -- L27 -- R28 -- L29 -- R30
                        -- L31 -- R-1
                ,
            ];

            % compute + label the lower segment (but do not draw it):
            path [
                name path=lower,
%                draw=blue,
%                thick,
                intersection segments=
                    of=origin and curve,
                    sequence=%
                        R1 -- L2 -- R3 -- L4 -- R5
                        -- R6 -- L7 -- R8 -- L9 -- R10
                        -- L11 -- R12 -- L13 -- R14 -- L15
                        -- L16 -- R17 -- L18 -- R19 -- L20
                        -- R21 -- L22 -- R23 -- L24 -- R25
                        -- L26 -- R27 -- L28 -- R29 -- L30
                        -- R31 -- L-1
                ,
            ];

            % store the first and last value of the `data' table
            pgfplotstablegetelem0yearofdata
                pgfmathsetmacroFirstXpgfplotsretval
            pgfplotstablegetrowsofdata
                    pgfmathsetmacroLastXpgfplotsretval-1
                pgfplotstablegetelemLastXyearofdata
                    pgfmathsetmacroLastXpgfplotsretval

            % now plot the filled areas between the "origin" path and the
            % computed "upper" and "lower" parts
            addplot [red!25]  fill between [
                of=origin and upper,
                % use another clip here to have a vertical start and end
                % of the filled area
                % (comment the next lines to see the difference)
                soft clip=
                    domain=FirstX:LastX
                ,
            ];
            addplot [blue!25]  fill between [
                of=origin and lower,
                soft clip=
                    domain=FirstX:LastX
                ,
            ];
        endaxis
    endtikzpicture

enddocument

imagen que muestra el resultado del código anterior

Te mostramos las reseñas y valoraciones de los lectores

Si posees alguna indecisión o disposición de perfeccionar nuestro artículo te insinuamos realizar una aclaración y con gusto lo leeremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *