Saltar al contenido

Cómo crear un espectro electromagnético usando el paquete pgfplots (junto con mapas de colores)

No busques más por todo internet porque estás al lugar correcto, contamos con la solución que buscas y sin liarte.

Solución:

%
documentclass[12pt]article
usepackage[dvipsnames,table]xcolor
usepackagesiunitx % SI-units
usepackagepgfplots
usepgfplotslibraryunits % to add units easily to axis
usepgfplotslibraryfillbetween % to fill inbetween curves
usepgfplotslibrarycolormaps % to create colormaps
pgfplotssetwidth=12.2cm, height=7cm
pgfplotssetcompat=newest %(making it only compatalbe with
%new releases of pgfplots)
pgfdeclarehorizontalshadingvisiblelight50bp
color(0.00000000000000bp)=(violet);
color(8.33333333333333bp)=(blue);
color(16.66666666666670bp)=(cyan);
color(25.00000000000000bp)=(green);
color(33.33333333333330bp)=(yellow);
color(41.66666666666670bp)=(orange);
color(50.00000000000000bp)=(red)
%

begindocument
begintikzpicture[fill between/on layer=axis grid]
beginaxis[
xlabel=Wavelength,
xticklabel style = font=tiny,yshift=0.2ex,
xmin=10^-5,
xmax=10^9,
x unit=simicrometer,
xmode=log,
ymin=0,
ymax=1,
height=3cm,
yticklabels=,
ytick=empty,
legend cell align=left,
legend style=at=(0.85,-0.77),anchor=north
]
addplot[draw=none, name path=start, forget plot] coordinates(10^-5,0)(10^-5,1);
addplot[draw=none, name path=gamma, forget plot] coordinates(10^-3,0)(10^-3,1);
addplot[draw=none, name path=xrays, forget plot] coordinates(10^-2,0)(10^-2,1);
addplot[draw=none, name path=uv, forget plot] coordinates(0.4,0)(0.4,1);
addplot[draw=none, name path=visible, forget plot] coordinates(0.7,0)(0.7,1);
addplot[draw=none, name path=ir, forget plot] coordinates(10^2.5,0)(10^2.5,1);
addplot[draw=none, name path=microwave, forget plot] coordinates(10^5,0)(10^5,1);
addplot[draw=none, name path=radiowave, forget plot] coordinates(10^9,0)(10^9,1);
addplot[violet!20, area legend] fill between[of=start and gamma];
addlegendentry$gamma$-ray
addplot[violet!60, area legend] fill between[of=gamma and xrays];
addlegendentryX-ray
addplot[violet, area legend] fill between[of=xrays and uv];
addlegendentryUltra violet
addplot[shading=visiblelight, area legend] fill between[of=uv and visible];
addlegendentryVisible light
addplot[red, area legend] fill between[of=visible and ir];
addlegendentryInfrared
addplot[Bittersweet, area legend] fill between[of=ir and microwave];
addlegendentryMicro wave
addplot[Brown, area legend] fill between[of=microwave and radiowave];
addlegendentryRadio wave
endaxis
endtikzpicture
enddocument

Salida de ejemplo:

Espectro electromagnético

Basado en la respuesta existente, también creé un enfoque. Tiene algunos problemas que podrían necesitar solución, especialmente para la escala ‘Espectro visible’ y los nombres de los colores en la parte inferior. Básicamente, también se desmorona para cualquier otro exponente de longitud de onda que no sean los especificados en el código.

documentclassarticle

usepackagetikz
usetikzlibrarycalc, positioning, shapes, backgrounds, fit, arrows
usepackagepgf-spectra

usepackagesiunitx

usepackagecontour

begindocument

pgfdeclarehorizontalshadingvisiblelight50bp% https://tex.stackexchange.com/a/348492/120853
    color(0bp)=(violet!25);
    color(8.33bp)=(blue!25);
    color(16.67bp)=(cyan!25);
    color(25bp)=(green!25);
    color(33.33bp)=(yellow!25);
    color(41.5bp)=(orange!25);
    color(50bp)=(red!25)
%

begintikzpicture[%
        raylabel/.style=font=scriptsize
    ]
    defminexponent-6
    defmaxexponent6
    defspectrumheight9em

    pgfmathtruncatemacronextminexponentminexponent + 1

    % Main foreach loop, drawing the wavelengths as powers of 10 in an alternating fashion: even on top, odd at bottom. Then connects them with help lines
    foreach [count=i, remember=exponent as previousexponent, evaluate=i as currentposition using int(i/2)] exponent in minexponent, nextminexponent, ..., maxexponent
        ifoddexponent
            defheight0
        else
            defheightspectrumheight
        fi

        % Anchor at baseline to get all nodes on same baseline.
        % https://tex.stackexchange.com/questions/133227/how-to-align-text-in-tikz-nodes-by-baseline#comment300863_133227
        node[anchor=base] (WAVELENGTH_exponent) at (exponent, height) contourwhitenumeexponent;

        ifnumi > 1
            ifoddi
                node (LABEL_currentposition)
                    at ($(WAVELENGTH_exponent)!0.5!(WAVELENGTH_previousexponent)$)
                    ;% This is left as a node as opposed to coordinate: fill it out with 'currentposition' for debugging
            else
                % Do not draw connection at exponent 1:
                pgfmathparseexponent != 1% pgfmathparse stores result (0 or 1) in macro pgfmathresult
                ifnumpgfmathresult = 1
                    draw[help lines]
                        (WAVELENGTH_previousexponent) --(WAVELENGTH_exponent)
                        node[midway] (CONNECTION_currentposition) % This is left as a node as opposed to coordinate: fill it out with 'currentposition' for debugging
                        coordinate[at start] (CONNECTION_currentposition_START)
                        coordinate[at end] (CONNECTION_currentposition_END);
                fi
            fi
        fi
    

    % Create an arrow shape that fits around all relevant nodes, but do not draw it.
    % Draw it manually later to leave out the 'bottom' of the arrow.
    % We still need this invisible arrow for lining up of coordinates
    node[
        single arrow,
        single arrow head extend=0pt,
        single arrow tip angle=150,% Inner angle of arrow tip
        fit=([xshift=-3em]CONNECTION_1_START)(CONNECTION_1_END)(CONNECTION_maxexponent_START)([xshift=5em]CONNECTION_maxexponent_END),
        inner sep=0pt
    ]
    (ARROW) ;

    node[align=center] (THERM) at ([yshift=3em]WAVELENGTH_1|-ARROW.after tail) thermal\radiation;% Only works because exponent 1 is between -1 and 3
    draw (THERM) -| ([yshift=-1.5em]WAVELENGTH_-1|-THERM);
    draw (THERM) -| ([yshift=-1.5em]WAVELENGTH_3|-THERM);

    % On background layer so already drawn arrow and scale lines cover it up nicely
    beginscope[on background layer]
        node[
            inner sep=0pt,
            outer sep=0pt,
            fit=-ARROW.after tail)([xshift=-2.2em]WAVELENGTH_1, shading=visiblelight]
            (SMALL_VISIBLE_LIGHT) ;

        shade[
            left color=white,
            right color=violet!25,
            middle color=violet!5,
            outer sep=0pt
            ]
            (CONNECTION_3_START) -- (CONNECTION_3_END) -- ([xshift=pgflinewidth]SMALL_VISIBLE_LIGHT.south west) -- ([xshift=pgflinewidth]SMALL_VISIBLE_LIGHT.north west) -- cycle;

        shade[
            left color=red!25,
            right color=white,
            middle color=red!5,
            outer sep=0pt,
            ]
            (CONNECTION_5_START) -- (CONNECTION_5_END) -- ([xshift=-pgflinewidth]SMALL_VISIBLE_LIGHT.south east) -- ([xshift=-pgflinewidth]SMALL_VISIBLE_LIGHT.north east) -- cycle;
    endscope

    % Some labels can be drawn automatically at the designated label coordinates:
    foreach [count=i] label in 
            Gamma\rays,
            X-rays,
            ,%Skip this one
            infrared
        
            node[raylabel, align=center] at (LABEL_i) label;
        

    % These do not fit the loop and are drawn manually:
    node[raylabel, align=right, anchor=north] at ([yshift=-1em]$(WAVELENGTH_-2)!0.45!(WAVELENGTH_0)$) Ultra-\violet;

    node[raylabel, fill=white] at (CONNECTION_6) radio waves;

    node[raylabel, left=0.1em of CONNECTION_1, align=right] cosmic\rays;

    node[
        draw,
        fill=black!20,
        below=4em of SMALL_VISIBLE_LIGHT,
        align=center,
        label=above:textbfVisible Spectrum
        ] (FULL_VISIBLE_LIGHT) %
        pgfspectra[width=13em,height=3em]\%pgfspectra also has a builtin axis which of course much better than this terrible approach, but it is in nanometer
            num0.38 hfillnum0.48 hfillnum0.58hfill num0.68 hfillnum0.78\
        hfill blue hspace0.1em green yellow hfill red hfill
    ;

    % Draw 'magnifying' trapeze, on background so it is covered by scale labels
    beginscope[on background layer]
        filldraw[help lines, fill=black!10] (FULL_VISIBLE_LIGHT.north east) -- (SMALL_VISIBLE_LIGHT.south east) -- (SMALL_VISIBLE_LIGHT.south west) -- (FULL_VISIBLE_LIGHT.north west) -- cycle;
    endscope

    % Draw around arrow manually, leaving its tail open
    draw[draw, thick] (ARROW.after tail) -- (ARROW.before head) -- (ARROW.before tip) -- (ARROW.tip) -- (ARROW.after tip) -- (ARROW.after head) -- (ARROW.before tail);
endtikzpicture
enddocument

dando un espectro electromagnético con algunas anotaciones, generado semiautomáticamente:

espectro electromagnético con anotaciones

Puntuaciones y comentarios

Finalizando este artículo puedes encontrar las aclaraciones de otros administradores, tú igualmente tienes la opción de mostrar el tuyo si te apetece.

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


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

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