%%%==============================================================================
%% Copyright 2025-present by Alceu Frigeri
%%
%% This work may be distributed and/or modified under the conditions of
%%
%% * The [LaTeX Project Public License](http://www.latex-project.org/lppl.txt),
%%   version 1.3c (or later), and/or
%% * The [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.html),
%%   version 3 (or later)
%%
%% This work has the LPPL maintenance status *maintained*.
%%
%% The Current Maintainer of this work is Alceu Frigeri
%%
%% This is version {1.1} {2025/11/15}
%%
%% The list of files that compose this work can be found in the README.md file at
%% https://ctan.org/pkg/tikzfxgraph
%%
%%%==============================================================================
\NeedsTeXFormat{LaTeX2e}[2022/06/01]

\ProvidesExplPackage
    {tikzfxgraph}
    {2025/11/15}
    {1.1}
    {tikzfxgraph Plotting functions in a simplified way.}

%%%%%%%
%%%
%%% Just an attempt of having my package's info in a regular way
%%% \Pkginfograb_set:nn {<pkg-name>} { props} for each and all.
%%%
%%%%%%%
\RequirePackage{pkginfograb}
\pkginfograb_set:nn { tikzfxgraph }
  {
     name        = {tikzfxgraph} ,
     prefix      = {tikzfxgraph} ,
     date        = {2025/11/15},
     version     = {1.1} ,
     description = {tikzfxgraph~ Plotting~ functions~ in~ a~ simplified~ way.}
  }
%%%%%%%
%%% End of cut-n-paste
%%%%%%%

\bool_new:N \l__tikzfxgraph_use_file_bool


\keys_define:nn { tikzfxgraph}
  {
    samples~ default .usage:n = general ,
    samples~ default .tl_set:N = \l__tikzfxgraph_samples_default_key_tl ,
    samples~ default .value_required:n  = true ,
    samples~ default .initial:n = {2000} ,

    use~ file .usage:n = general,
	  use~ file .bool_set:N = \l__tikzfxgraph_use_file_key_bool,  
    use~ file .value_forbidden:n = true ,

    no~ domain~ warning .usage:n = general,
	  no~ domain~ warning .code:n = 
      { 
        \msg_redirect_name:nnn {tikzfxgraph} { x domain} { none }
      }
  }
\ProcessKeyOptions [tikzfxgraph] 
  

\msg_new:nnnn {tikzfxgraph} { no explicit domain}
  {
    (ID:#1)~You~ didn't~ explicitily~ define~ a~ range/domain~ for~ the~ x~ axis.
  }
  {
    You~ didn't~ explicitily~ define~ a~ range/domain~ for~ the~ x~ axis.
    ~Error~ Code~ ID:<#1>.
  }

\msg_new:nnnn {tikzfxgraph} { ticks min max}
  {
    (ID:#1)~Missing~ min~ and~ max~ values.~Got~#2
  }
  {
    You~ need~ to~ supply~ both~ min~ and~ max~ values.
    ~Error~ Code~ ID:<#1>.
  }

\msg_new:nnnn {tikzfxgraph} { ticks N delta}
  {
    (ID:#1)~Missing~ N~ or~ delta.~ ticks~ not~ generated.
  }
  {
    You~ need~ to~ supply~ at~ least~ N~ or~ delta.~ ticks~ not~ generated.
    ~Error~ Code~ ID:<#1>.
  }
  

\msg_new:nnnn {tikzfxgraph} { log min max}
  {
    (ID:#1)~For~ a~ log~ axis~ both~ min~ max~ values~ must~ be~ positive.~Got~#2
  }
  {
    For~ a~ log~ axis~ both~ min~ max~ values~ must~ be~ positive.
    ~Error~ Code~ ID:<#1>.
  }

\msg_new:nnnn {tikzfxgraph} { x domain}
  {
    (ID:#1)~X~ min/max~ isn't~ explicitly~ defined.~ This~ might~ be~ an~ error.
  }
  {
    X~ min/max~ isn't~ explicitly~ defined.~ This~ might~ be~ an~ error.
    ~Error~ Code~ ID:<#1>.
  }
  
\msg_new:nnnn {tikzfxgraph} {fxset already defined}
  {
    (ID:#1)~fxset~ #2~ already~ defined.
  }
  {
    The~ fxset~ #2~ is~ already~ defined.
    ~Error~ Code~ ID:<#1>.
  }

\msg_new:nnnn {tikzfxgraph} {fxset undefined}
  {
    (ID:#1)~invalid/undefined~ fxset~ #2.
  }
  {
    The~ fxset~ #1~ doesn't~ exist,~ isn't~ defined.
    ~Error~ Code~ ID:<#1>.
  }



\pgfplotscreateplotcyclelist{fxgraph~ color~ list}
  {
    red!80!black,
    green!80!black,
    blue!80!black,
    black,
    brown!70!black,
    teal!80!black, 
    orange!80!black,
    violet!80!black,
    cyan!80!black,
    magenta!80!black,
    yellow!75!black,
    black!60!white
  }
\pgfplotscreateplotcyclelist{fxgraph~ line~ list}
  {
    solid,
    solid,
    solid,
    dashed,
    dashed,
    dashed,
    dashdotdotted,
    dashdotdotted,
    dashdotdotted
  }

\pgfkeys{
    pgfplots,
    linear~ axis/.style =
      {
        grid=both,
        tick~ align=outside,
        width=0.8\textwidth,
        height=0.35\textwidth,
        axis~ line~ style={color=black!85!white,very~ thick},
        axis~ x~ line=bottom,
        axis~ y~ line=left,
        cycle~ multiindex*~ list = 
          {
            fxgraph~ color~ list\nextlist fxgraph~ line~ list
          } ,
        legend~ style = 
          {
            font=\footnotesize,
            legend~ pos = outer~ north~ east,
            draw = none ,
            inner~ xsep=0pt,
            inner~ ysep=0pt,
            anchor = west ,
          } ,
      } ,
    semilog~ x~ axis/.style =
      {
        linear~ axis,
        log~ identify~ minor~ tick~ positions=true,        
%        log~ basis~ x = 10,
      } ,
    semilog~ y~ axis/.style =
      {
        linear~ axis,
        log~ identify~ minor~ tick~ positions=true,        
%        log~ basis~ y = 10,
      } ,
    loglog~ axis/.style =
      {
        linear~ axis,
        log~ identify~ minor~ tick~ positions=true,        
%        log~ basis~ x = 10,
%        log~ basis~ y = 10,
      }
  }



\int_new:N \l__tikzfxgraph_tmpi_int
\seq_new:N \l__tikzfxgraph_tick_tmpi_seq
\fp_new:N  \l__tikzfxgraph_tmpi_fp
\fp_new:N  \l__tikzfxgraph_delta_tmpi_fp
\tl_new:N  \l__tikzfxgraph_nill_tl
\tl_new:N  \l__tikzfxgraph_tmpi_tl

\cs_generate_variant:Nn \fp_set:Nn {Ne}
\cs_generate_variant:Nn \fp_add:Nn {Ne}
\cs_generate_variant:Nn \seq_put_right:Nn {Ne}


\tl_new:N \l__tikzfxgraph_axis_kind_key_tl
\tl_new:N \l__tikzfxgraph_axis_style_key_tl
\tl_new:N \l__tikzfxgraph_Xaxis_type_key_tl
\tl_new:N \l__tikzfxgraph_Yaxis_type_key_tl

\tl_new:N \l__tikzfxgraph_Xticks_key_tl
\tl_new:N \l__tikzfxgraph_Xmin_key_tl
\tl_new:N \l__tikzfxgraph_Xmax_key_tl
\tl_new:N \l__tikzfxgraph_Xunits_key_tl

\tl_new:N \l__tikzfxgraph_Yticks_key_tl
\tl_new:N \l__tikzfxgraph_Ymin_key_tl
\tl_new:N \l__tikzfxgraph_Ymax_key_tl
\tl_new:N \l__tikzfxgraph_Yunits_key_tl

\tl_new:N \l__tikzfxgraph_functions_tl

\tl_new:N \l__tikzfxgraph_fxstyles_key_tl

\clist_new:N \l__tikzfxgraph_fxset_key_clist


\tl_new:N \l__tikzfxgraph_tmpa_tl
\tl_new:N \l__tikzfxgraph_tmpb_tl  
\tl_new:N \l__tikzfxgraph_tmpc_tl  


\keys_define:nn  {tikzfxgraph / axis kind}
  {
    linear .usage:n = general ,
    linear .code:n = 
      {
        \tl_set:Nn \l__tikzfxgraph_axis_kind_key_tl {axis}
        \tl_set:Nn \l__tikzfxgraph_axis_basestyle_key_tl {linear~ axis}
        \tl_set:Nn \l__tikzfxgraph_Xaxis_type_key_tl {linear}
        \tl_set:Nn \l__tikzfxgraph_Yaxis_type_key_tl {linear}
      } ,
    linear .value_forbidden:n = true ,

    loglog .usage:n = general ,
    loglog .code:n = 
      {
        \tl_set:Nn \l__tikzfxgraph_axis_kind_key_tl {loglogaxis}
        \tl_set:Nn \l__tikzfxgraph_axis_basestyle_key_tl {loglog~ axis}
        \tl_set:Nn \l__tikzfxgraph_Xaxis_type_key_tl {log}
        \tl_set:Nn \l__tikzfxgraph_Yaxis_type_key_tl {log}
      } ,
    loglog .value_forbidden:n = true ,

    semilog~ x .usage:n = general ,
    semilog~ x .code:n = 
      {
        \tl_set:Nn \l__tikzfxgraph_axis_kind_key_tl {semilogxaxis}
        \tl_set:Nn \l__tikzfxgraph_axis_basestyle_key_tl {semilog~ x~ axis}
        \tl_set:Nn \l__tikzfxgraph_Xaxis_type_key_tl {log}
        \tl_set:Nn \l__tikzfxgraph_Yaxis_type_key_tl {linear}
      } ,
    semilog~ x .value_forbidden:n = true ,

    semilog~ y .usage:n = general ,
    semilog~ y .code:n = 
      {
        \tl_set:Nn \l__tikzfxgraph_axis_kind_key_tl {semilogyaxis}
        \tl_set:Nn \l__tikzfxgraph_axis_basestyle_key_tl {semilog~ y~ axis}
        \tl_set:Nn \l__tikzfxgraph_Xaxis_type_key_tl {linear}
        \tl_set:Nn \l__tikzfxgraph_Yaxis_type_key_tl {log}
      } ,  
    semilog~ y .value_forbidden:n = true ,
  }
  
\cs_new_protected:Npn \__tikzfxgraph_axiskind_init:n #1
  {
    \keys_set:nn {tikzfxgraph / axis kind} {#1}
  }
  
  
\keys_define:nn   {tikzfxgraph / axis ticks}
  {
    x~ ticks .usage:n = general ,
    x~ ticks .code:n = 
      {
        \__tikzfxgraph_ticks_set:NVn \l__tikzfxgraph_Xticks_key_tl \l__tikzfxgraph_Xaxis_type_key_tl {#1}
        
        \tl_set:NV \l__tikzfxgraph_Xmin_key_tl \l__tikzfxgraph_min_key_tl
        \tl_set:NV \l__tikzfxgraph_Xmax_key_tl \l__tikzfxgraph_max_key_tl
        \tl_set:NV \l__tikzfxgraph_Xunits_key_tl \l__tikzfxgraph_units_key_tl
      } ,
    x~ ticks .value_required:n = true ,

    y~ ticks .usage:n = general ,
    y~ ticks .code:n = 
      {
        \__tikzfxgraph_ticks_set:NVn \l__tikzfxgraph_Yticks_key_tl \l__tikzfxgraph_Yaxis_type_key_tl {#1}
        
        \tl_set:NV \l__tikzfxgraph_Ymin_key_tl \l__tikzfxgraph_min_key_tl
        \tl_set:NV \l__tikzfxgraph_Ymax_key_tl \l__tikzfxgraph_max_key_tl
        \tl_set:NV \l__tikzfxgraph_Yunits_key_tl \l__tikzfxgraph_units_key_tl
      } ,
    y~ ticks .value_required:n = true ,
  }

\cs_new_protected:Npn \__tikzfxgraph_axisticks_init: 
  {
    \tl_clear:N \l__tikzfxgraph_Xticks_key_tl
    \tl_clear:N \l__tikzfxgraph_Xmin_key_tl
    \tl_clear:N \l__tikzfxgraph_Xmax_key_tl
    \tl_clear:N \l__tikzfxgraph_Xunits_key_tl
    \tl_clear:N \l__tikzfxgraph_Yticks_key_tl
    \tl_clear:N \l__tikzfxgraph_Ymin_key_tl
    \tl_clear:N \l__tikzfxgraph_Ymax_key_tl
    \tl_clear:N \l__tikzfxgraph_Yunits_key_tl    
  }


  
\keys_define:nn {} 
  {
    tikzfxgraph / graph desc .inherit:n = 
      {
        tikzfxgraph / axis kind , 
        tikzfxgraph / axis ticks , 
      }
  }

\keys_define:nn {tikzfxgraph / graph desc}
  {
    sans~ tikz picture .usage:n = general ,
    sans~ tikz picture .bool_set:N = \l__tikzfxgraph_sanstikz_key_bool ,
  
    without~ tikz picture .usage:n = general ,
    without~ tikz picture .bool_set:N = \l__tikzfxgraph_sanstikz_key_bool ,

    use~ file .usage:n = general,
	  use~ file .bool_set:N = \l__tikzfxgraph_use_file_key_bool,

    function .usage:n = general ,
    function .code:n = 
      {
        \__tikzfxgraph_fxset_append:nn {default _ set}{#1}
      } ,
    function .value_required:n = true ,

    fx~ set .usage:n = general ,
    fx~ set .clist_set:N = \l__tikzfxgraph_fxset_key_clist ,
    fx~ set .value_required:n = true ,

    unknown .code:n =
      {
        \__tikzfxgraph_fxstyles_setkey:NVn 
          \l__tikzfxgraph_axis_style_key_tl 
          \l_keys_key_str
          {#1}
      } ,
  }

\cs_new_protected:Npn \__tikzfxgraph_graphdesc_init:
  {
        \__tikzfxgraph_fxset_clear:n {default _ set}  
        \clist_clear:N \l__tikzfxgraph_fxset_key_clist    
        \bool_set_false:N \l__tikzfxgraph_sanstikz_key_bool
        \tl_clear:N \l__tikzfxgraph_axis_style_key_tl

    \__tikzfxgraph_axisticks_init:
    \__tikzfxgraph_axiskind_init:n {linear}
  }


\keys_define:nn {} 
  {
    tikzfxgraph / keys desc .inherit:n = 
      {
        tikzfxgraph / axis kind , 
        tikzfxgraph / axis ticks , 
      }
  }

\keys_define:nn {tikzfxgraph / keys desc}
  {  
    unknown .code:n =
      {
        \__tikzfxgraph_fxstyles_setkey:NVn 
          \l__tikzfxgraph_axis_style_key_tl 
          \l_keys_key_str
          {#1}
      } ,
  }


\cs_new_protected:Npn \__tikzfxgraph_keysdesc_init:
  {
    \tl_clear:N \l__tikzfxgraph_axis_style_key_tl

    \__tikzfxgraph_axisticks_init:
    \__tikzfxgraph_axiskind_init:n {linear}
  }


\keys_define:nn {tikzfxgraph / ticks}
  {
    min .usage:n = general ,
    min .tl_set:N = \l__tikzfxgraph_min_key_tl ,
    min .value_required:n  = true ,
    
    max .usage:n = general ,
    max .tl_set:N = \l__tikzfxgraph_max_key_tl ,
    max .value_required:n  = true ,

    delta .usage:n = general ,
    delta .tl_set:N = \l__tikzfxgraph_delta_key_tl ,
    delta .value_required:n  = true ,

    N .usage:n = general ,
    N .tl_set:N = \l__tikzfxgraph_N_key_tl ,
    N .value_required:n  = true ,

    units .usage:n = general ,
    units .tl_set:N = \l__tikzfxgraph_units_key_tl ,
    units .value_required:n  = true ,
    
    phi .usage:n = general ,
    phi .code:n = 
      {
        \tl_set:Nn \l__tikzfxgraph_min_key_tl {-3.14159265}
        \tl_set:Nn \l__tikzfxgraph_max_key_tl { 3.14159265}
        \tl_set:Nn \l__tikzfxgraph_N_key_tl   { 8 }        
        \tl_set:Nn \l__tikzfxgraph_units_key_tl   { rad }
      } ,
    phi .value_forbidden:n  = true ,
    
    db .usage:n = general ,
    db .code:n = 
      {
        \tl_set:Nn \l__tikzfxgraph_min_key_tl {-20}
        \tl_set:Nn \l__tikzfxgraph_max_key_tl { 80}
        \tl_set:Nn \l__tikzfxgraph_N_key_tl   { 5 }
        \tl_set:Nn \l__tikzfxgraph_units_key_tl   { db }
      } ,
    db .value_forbidden:n  = true ,
  }

\cs_new_protected:Npn \__tikzfxgraph_ticks_init:
  {
    \tl_clear:N \l__tikzfxgraph_min_key_tl
    \tl_clear:N \l__tikzfxgraph_max_key_tl
    \tl_clear:N \l__tikzfxgraph_delta_key_tl
    \tl_clear:N \l__tikzfxgraph_N_key_tl
    \tl_clear:N \l__tikzfxgraph_units_key_tl
  }


\keys_define:nn {tikzfxgraph / fx set}
  {   
    fx .usage:n = general ,
    fx .tl_set:N = \l__tikzfxgraph_fx_key_tl ,
    fx .value_required:n  = true ,
    
    id .usage:n = general ,
    id .tl_set:N = \l__tikzfxgraph_fxid_key_tl ,
    id .value_required:n  = true ,
    
    legend .usage:n = general ,
    legend .tl_set:N = \l__tikzfxgraph_fxlegend_key_tl ,
    legend .value_required:n  = true ,
    
    use~ file .usage:n = general ,
	  use~ file .bool_set:N = \l__tikzfxgraph_fx_use_file_key_bool ,
    use~ file .value_forbidden:n = true ,
    
    samples .usage:n = general ,
    samples .tl_set:N = \l__tikzfxgraph_samples_key_tl ,
    samples .value_required:n  = true ,
    
    unknown .code:n =
      {
        \__tikzfxgraph_fxstyles_setkey:NVn 
          \l__tikzfxgraph_fxstyles_key_tl 
          \l_keys_key_str
          {#1}
      } ,
  }


\cs_new_protected:Npn \__tikzfxgraph_fxset_init:
  {
    \tl_clear:N \l__tikzfxgraph_fxstyles_key_tl
    \tl_clear:N \l__tikzfxgraph_fx_key_tl
    \tl_clear:N \l__tikzfxgraph_fxid_key_tl
    \tl_clear:N \l__tikzfxgraph_fxlegend_key_tl
    \tl_set_eq:NN \l__tikzfxgraph_samples_key_tl \l__tikzfxgraph_samples_default_key_tl 
    \bool_set_false:N \l__tikzfxgraph_fx_use_file_key_bool
  }


\prg_generate_conditional_variant:Nnn \fp_compare:nNn {eNn} {p , T , F , TF}


\cs_new_protected:Npn  \__tikzfxgraph_fxstyles_setkey:Nnn #1#2#3
  {
    \tl_if_blank:VF #1
      { \tl_put_right:Nn #1 , }
     \tl_if_blank:nTF {#3} 
      { \tl_put_right:Nn #1 {#2} }
      { \tl_put_right:Nn #1 {#2={#3}} }
  }
  
\cs_generate_variant:Nn  \__tikzfxgraph_fxstyles_setkey:Nnn {NVn}


\cs_new_protected:Npn \__tikzfxgraph_ticks_set:Nnn #1#2#3
  {   
    \__tikzfxgraph_ticks_init:
    
    \keys_set:nn {tikzfxgraph / ticks}
      {#3}
    \bool_lazy_or:nnTF 
      {\tl_if_blank_p:V \l__tikzfxgraph_min_key_tl} {\tl_if_blank_p:V \l__tikzfxgraph_max_key_tl}
      {
        \msg_error:nnne {tikzfxgraph} {ticks min max}{ticks-01}
          {min:<\l__tikzfxgraph_min_key_tl> ~-~ max:<\l__tikzfxgraph_max_key_tl>}
      }
      {
        \tl_if_blank:VTF \l__tikzfxgraph_N_key_tl
          {
            \tl_if_blank:VTF \l__tikzfxgraph_delta_key_tl
              {
                \msg_warning:nnn {tikzfxgraph} {ticks N delta}{ticks-02}
                \tl_clear:N #1
              }
              {
                  \int_zero:N \l__tikzfxgraph_tmpi_int
                  \seq_clear:N \l__tikzfxgraph_tick_tmpi_seq
                \str_if_eq:nnTF {#2}{linear}
                  {  
                    \fp_set:Ne \l__tikzfxgraph_tmpi_fp {\l__tikzfxgraph_min_key_tl}
                    \fp_set:Ne \l__tikzfxgraph_delta_tmpi_fp { \l__tikzfxgraph_delta_key_tl }
                    \seq_put_right:Ne \l__tikzfxgraph_tick_tmpi_seq {\fp_use:N \l__tikzfxgraph_tmpi_fp}
                    \fp_while_do:nNnn
                      {\l__tikzfxgraph_tmpi_fp} < {\l__tikzfxgraph_max_key_tl}
                      {
                        \fp_add:Nn  \l__tikzfxgraph_tmpi_fp {\l__tikzfxgraph_delta_tmpi_fp}
                        \seq_put_right:Ne \l__tikzfxgraph_tick_tmpi_seq {\fp_use:N \l__tikzfxgraph_tmpi_fp}
                      }
                    \tl_set:Ne #1 {\seq_use:Nn \l__tikzfxgraph_tick_tmpi_seq {~,~}}
                  }
                  { %log
                    \bool_lazy_and:nnTF
                      { \fp_compare_p:eNn {\l__tikzfxgraph_max_key_tl} > {0} } { \fp_compare_p:eNn {\l__tikzfxgraph_min_key_tl} > {0} }
                      {
                      \fp_set:Ne \l__tikzfxgraph_tmpi_fp {ln(\l__tikzfxgraph_min_key_tl)}
                      \fp_set:Ne \l__tikzfxgraph_tmpii_fp {ln(\l__tikzfxgraph_max_key_tl)}
                      \fp_set:Ne \l__tikzfxgraph_delta_tmpi_fp { ln(\l__tikzfxgraph_delta_key_tl) }
                        \seq_put_right:Ne \l__tikzfxgraph_tick_tmpi_seq {\fp_eval:n {exp(\l__tikzfxgraph_tmpi_fp)}}
                        \fp_while_do:nNnn
                          {\l__tikzfxgraph_tmpi_fp} < {\l__tikzfxgraph_tmpii_fp}
                          {
                            \fp_add:Nn  \l__tikzfxgraph_tmpi_fp {\l__tikzfxgraph_delta_tmpi_fp}
                            \seq_put_right:Ne \l__tikzfxgraph_tick_tmpi_seq {\fp_eval:n {exp(\l__tikzfxgraph_tmpi_fp)}}
                          }
                        \tl_set:Ne #1 {\seq_use:Nn \l__tikzfxgraph_tick_tmpi_seq {~,~}}
                      }
                      {
                        \msg_error:nnne {tikzfxgraph}{log min max}{ticks-03}
                          {min:<\l__tikzfxgraph_min_key_tl> ~-~ max:<\l__tikzfxgraph_max_key_tl>} % both must be positive
                      }
                  }
              }
          }
          {
              \int_zero:N \l__tikzfxgraph_tmpi_int
              \seq_clear:N \l__tikzfxgraph_tick_tmpi_seq
            \str_if_eq:nnTF {#2}{linear}
              {  
                \fp_set:Ne \l__tikzfxgraph_tmpi_fp {\l__tikzfxgraph_min_key_tl}
                \fp_set:Ne \l__tikzfxgraph_delta_tmpi_fp { (\l__tikzfxgraph_max_key_tl - \l__tikzfxgraph_min_key_tl) / \l__tikzfxgraph_N_key_tl}
                \seq_put_right:Ne \l__tikzfxgraph_tick_tmpi_seq {\fp_use:N \l__tikzfxgraph_tmpi_fp}
                \int_while_do:nNnn
                  {\l__tikzfxgraph_tmpi_int} < {\l__tikzfxgraph_N_key_tl}
                  {
                    \fp_add:Nn  \l__tikzfxgraph_tmpi_fp {\l__tikzfxgraph_delta_tmpi_fp}
                    \seq_put_right:Ne \l__tikzfxgraph_tick_tmpi_seq {\fp_use:N \l__tikzfxgraph_tmpi_fp}
                    \int_incr:N \l__tikzfxgraph_tmpi_int
                  }
                \tl_set:Ne #1 {\seq_use:Nn \l__tikzfxgraph_tick_tmpi_seq {~,~}}
              }
              { %log
                \bool_lazy_and:nnTF
                  { \fp_compare_p:eNn {\l__tikzfxgraph_max_key_tl} > {0} } { \fp_compare_p:eNn {\l__tikzfxgraph_min_key_tl} > {0} }
                  {
                  \fp_set:Ne \l__tikzfxgraph_tmpi_fp {ln(\l__tikzfxgraph_min_key_tl)}
                  \fp_set:Ne \l__tikzfxgraph_delta_tmpi_fp { (ln(\l__tikzfxgraph_max_key_tl) - ln(\l__tikzfxgraph_min_key_tl)) / \l__tikzfxgraph_N_key_tl}
                    \seq_put_right:Ne \l__tikzfxgraph_tick_tmpi_seq {\fp_eval:n {exp(\l__tikzfxgraph_tmpi_fp)}}
                    \int_while_do:nNnn
                      {\l__tikzfxgraph_tmpi_int} < {\l__tikzfxgraph_N_key_tl}
                      {
                        \fp_add:Nn  \l__tikzfxgraph_tmpi_fp {\l__tikzfxgraph_delta_tmpi_fp}
                        \seq_put_right:Ne \l__tikzfxgraph_tick_tmpi_seq {\fp_eval:n {exp(\l__tikzfxgraph_tmpi_fp)}}
                        \int_incr:N \l__tikzfxgraph_tmpi_int
                      }
                    \tl_set:Ne #1 {\seq_use:Nn \l__tikzfxgraph_tick_tmpi_seq {~,~}}
                  }
                  {
                    \msg_error:nnne {tikzfxgraph}{log min max}{ticks-04}
                      {min:<\l__tikzfxgraph_min_key_tl> ~-~ max:<\l__tikzfxgraph_max_key_tl>} % both must be positive
                  }
              }
          }
      }
  }
\cs_generate_variant:Nn \__tikzfxgraph_ticks_set:Nnn { NVn }  


\cs_new_protected:Npn \__tikzfxgraph_seq_put:Nnn #1#2#3
  {
    \seq_put_right:Nn #1 
      { {#2}{#3} }
  }
\cs_generate_variant:Nn   \__tikzfxgraph_seq_put:Nnn {cVV}
  
\cs_new_protected:Npn \__tikzfxgraph_fxset_addplot:nn #1#2
  {
    \__tikzfxgraph_fxset_init:
      
    \keys_set:nn {tikzfxgraph / fx set}
      {#2}
   
    \tl_set:Ne \l__tikzfxgraph_tmpa_tl {samples=\l__tikzfxgraph_samples_key_tl}
    \tl_if_blank:VTF \l__tikzfxgraph_fxid_key_tl
      {
        \tl_clear:N \l__tikzfxgraph_tmpc_tl
      }
      {
        \tl_put_right:Ne \l__tikzfxgraph_tmpa_tl {,id=\l__tikzfxgraph_fxid_key_tl}
        \exp_args:Ne \IfFileExists {\jobname . \l__tikzfxgraph_fxid_key_tl .table}
          {
            \tl_set:Ne \l__tikzfxgraph_tmpc_tl 
              {\exp_not:N\addplot table [x ~ index=0,y ~ index=1,header=false] {\jobname . \l__tikzfxgraph_fxid_key_tl .table};}
          }
          {
            \tl_clear:N \l__tikzfxgraph_tmpc_tl
          }
      }
      
    \tl_set:Ne \l__tikzfxgraph_tmpb_tl
      {
        \exp_not:N\addplot+ gnuplot 
          [ \l__tikzfxgraph_tmpa_tl , \l__tikzfxgraph_fxstyles_key_tl ]
          {\l__tikzfxgraph_fx_key_tl};
      }
    \tl_if_blank:VF \l__tikzfxgraph_fxlegend_key_tl
      {
        \tl_put_right:Ne \l__tikzfxgraph_tmpb_tl
          {
            \exp_not:N\addlegendentry {\l__tikzfxgraph_fxlegend_key_tl}
          }
        \tl_if_blank:VF \l__tikzfxgraph_tmpc_tl
          {
            \tl_put_right:Ne \l__tikzfxgraph_tmpc_tl
              {
                \exp_not:N\addlegendentry {\l__tikzfxgraph_fxlegend_key_tl}
              }
          }
      }

    \tl_if_blank:VTF \l__tikzfxgraph_tmpc_tl
      {
        \__tikzfxgraph_seq_put:cVV 
          {l__tikzfxgraph_fxset_ #1 _seq} 
          \l__tikzfxgraph_tmpb_tl
          \l__tikzfxgraph_tmpb_tl
      }
      {
        \bool_if:NTF \l__tikzfxgraph_fx_use_file_key_bool
          {
            \__tikzfxgraph_seq_put:cVV 
              {l__tikzfxgraph_fxset_ #1 _seq} 
              \l__tikzfxgraph_tmpc_tl
              \l__tikzfxgraph_tmpc_tl
          }
          {
            \__tikzfxgraph_seq_put:cVV 
              {l__tikzfxgraph_fxset_ #1 _seq} 
              \l__tikzfxgraph_tmpb_tl
              \l__tikzfxgraph_tmpc_tl
          }
      }
  }  
  
\cs_new_protected:Npn \__tikzfxgraph_fxset_new:n #1
  {
    \seq_if_exist:cTF {l__tikzfxgraph_fxset_ #1 _seq}
      {
        \msg_error:nnnn {tikzfxgraph}{fxset already defined}{fxset-01}{#1}
      }
      {
        \seq_new:c {l__tikzfxgraph_fxset_ #1 _seq}
      }
  }  
  
  
\__tikzfxgraph_fxset_new:n {default _ set}  

\cs_new_protected:Npn \__tikzfxgraph_fxset_clear:n #1
  {
    \seq_if_exist:cTF {l__tikzfxgraph_fxset_ #1 _seq}
      {
        \seq_clear:c {l__tikzfxgraph_fxset_ #1 _seq}
      }
      {
        \msg_error:nnnn {tikzfxgraph}{fxset undefined}{fxset-02}{#1}
      }
  }  



\cs_new_protected:Npn \__tikzfxgraph_fxset_append:nn #1#2
  {
    \seq_if_exist:cTF {l__tikzfxgraph_fxset_ #1 _seq} 
      {
        \__tikzfxgraph_fxset_addplot:nn {#1}{#2}
      }
      {
        \msg_error:nnnn {tikzfxgraph}{fxset undefined}{fxset-03}{#1}
      }
   }  
  
\NewDocumentCommand{\fxsetnew}{m}
  { \__tikzfxgraph_fxset_new:n {#1} }
  
  
\NewDocumentCommand{\fxsetappend}{mm}
  { \__tikzfxgraph_fxset_append:nn {#1}{#2} }


\NewDocumentCommand{\fxsetnewstyle}{mm}
  {
    \__tikzfxgraph_keysdesc_init:
      
    \keys_set:nn {tikzfxgraph / keys desc}
      {#2}
    \__tikzfxgraph_set_keys:N \l__tikzfxgraph_stylekeys_set_tl
    \use:e 
      {
        \exp_not:N\pgfkeys{pgfplots,
          #1/.style = 
            { \l__tikzfxgraph_stylekeys_set_tl }   
        }   
      }
  }
  

\cs_new_protected:Npn \__tikzfxgraph_axisdraw:nnnn #1#2#3#4
  {
    \bool_if:NTF \l__tikzfxgraph_sanstikz_key_bool
      {
        \tl_set:Nn \l__tikzfxgraph_tmpa_tl
          { 
            \begin{#1}[#2]
              #3
              #4
            \end{#1}
          }
      }
      {
        \tl_set:Nn \l__tikzfxgraph_tmpa_tl
          { 
            \begin{tikzpicture}
              \begin{#1}[#2]
                #3
                #4
              \end{#1}
            \end{tikzpicture}
          }
      }
    \l__tikzfxgraph_tmpa_tl
  }
  
\cs_generate_variant:Nn \__tikzfxgraph_axisdraw:nnnn {VVVn}

\cs_new_protected:Npn \__tikzfxgraph_set_keys:Nnnn #1#2#3#4
  {
    \tl_if_blank:nTF {#2}
      { \tl_clear:N #1 }
      { \tl_set:Nn #1 {#2} }
    \tl_if_blank:nF {#3}
      { \tl_put_right:Nn #1 {xtick={#3},} } 
    \tl_if_blank:nF {#4}
      { \tl_put_right:Nn #1 {ytick={#4}} } 
  }

\cs_generate_variant:Nn \__tikzfxgraph_set_keys:Nnnn {NVVV}

\tl_new:N \l__tikzfxgraph_stylekeys_set_tl

\cs_new_protected:Npn \__tikzfxgraph_set_keys:N #1 
  {
    \tl_clear:N \l__tikzfxgraph_tmpa_tl
    \tl_if_blank:VF \l__tikzfxgraph_axis_style_key_tl
      {
        \tl_set:NV \l__tikzfxgraph_tmpa_tl \l__tikzfxgraph_axis_style_key_tl
        \tl_put_right:Nn \l__tikzfxgraph_tmpa_tl {,}
      }
      
    \bool_lazy_or:nnTF {\tl_if_blank_p:V \l__tikzfxgraph_Xmin_key_tl } {\tl_if_blank_p:V \l__tikzfxgraph_Xmax_key_tl}
      {
        \msg_warning:nnn {tikzfxgraph}{x domain}{keys-01}
      }
      {
        \tl_put_right:Ne \l__tikzfxgraph_tmpa_tl 
          {
            xmin=\l__tikzfxgraph_Xmin_key_tl,
            xmax=\l__tikzfxgraph_Xmax_key_tl,
            domain=\l__tikzfxgraph_Xmin_key_tl : \l__tikzfxgraph_Xmax_key_tl,
          }
      }
    \tl_if_blank:VF \l__tikzfxgraph_Xunits_key_tl
      {
        \tl_put_right:Ne \l__tikzfxgraph_tmpa_tl 
          { x~ unit=\l__tikzfxgraph_Xunits_key_tl, }
      }
    \bool_lazy_or:nnF {\tl_if_blank_p:V \l__tikzfxgraph_Ymin_key_tl} {\tl_if_blank_p:V \l__tikzfxgraph_Ymax_key_tl}
      {
        \tl_put_right:Ne \l__tikzfxgraph_tmpa_tl 
          {
            ymin=\l__tikzfxgraph_Ymin_key_tl,
            ymax=\l__tikzfxgraph_Ymax_key_tl,
          }
      }
    \tl_if_blank:VF \l__tikzfxgraph_Yunits_key_tl
      {
        \tl_put_right:Ne \l__tikzfxgraph_tmpa_tl 
          { y~ unit=\l__tikzfxgraph_Yunits_key_tl, }
      }
    
    \__tikzfxgraph_set_keys:NVVV
      #1
      \l__tikzfxgraph_tmpa_tl
      \l__tikzfxgraph_Xticks_key_tl
      \l__tikzfxgraph_Yticks_key_tl
  
  }


\NewDocumentCommand{\fxgraphdraw}{m}
  {
    \begin{fxgraph}{#1}
    \end{fxgraph}
  }
  
  

\cs_new:Npn \__tikzfxgraph_i_ii:Nnn #1#2#3
  {
    \tl_put_right:Nn #1 {#2}
  }
\cs_new:Npn \__tikzfxgraph_i_iii:Nnn #1#2#3
  {
    \tl_put_right:Nn #1 {#3}
  }

\NewDocumentEnvironment{fxgraph}{m +b}
  {
    \__tikzfxgraph_graphdesc_init:
      
    \keys_set:nn {tikzfxgraph / graph desc}
      {#1}
    
    \__tikzfxgraph_set_keys:N \l__tikzfxgraph_stylekeys_set_tl         
    
    \tl_clear:N \l__tikzfxgraph_tmpb_tl
    \clist_put_left:Nn \l__tikzfxgraph_fxset_key_clist {default_set}
    
    \bool_if:NTF \l__tikzfxgraph_use_file_key_bool
      { \cs_set_eq:NN \__tikzfxgraph_map:Nnn \__tikzfxgraph_i_iii:Nnn }
      { \cs_set_eq:NN \__tikzfxgraph_map:Nnn \__tikzfxgraph_i_ii:Nnn }
    
    \clist_map_inline:Nn \l__tikzfxgraph_fxset_key_clist
      {
        \seq_if_exist:cTF {l__tikzfxgraph_fxset_ ##1 _seq}
          {
            \seq_map_inline:cn {l__tikzfxgraph_fxset_ ##1 _seq}
              {\__tikzfxgraph_map:Nnn \l__tikzfxgraph_tmpb_tl ####1} %% remember: each item is composed of two n's: {}{}
          }
          {
            \msg_error:nnnn {tikzfxgraph} {fxset undefined}{set-02}{##1}
          }
      }

      \tl_set:NV \l__tikzfxgraph_tmpa_tl \l__tikzfxgraph_axis_basestyle_key_tl
      \tl_put_right:Nn \l__tikzfxgraph_tmpa_tl {,}
      \tl_put_right:NV \l__tikzfxgraph_tmpa_tl \l__tikzfxgraph_stylekeys_set_tl

    \__tikzfxgraph_axisdraw:VVVn
      \l__tikzfxgraph_axis_kind_key_tl
      \l__tikzfxgraph_tmpa_tl
      \l__tikzfxgraph_tmpb_tl    
      {#2}
  }
  {}
