diff --git a/.gitignore b/.gitignore index b89e9bf..218a6f1 100644 --- a/.gitignore +++ b/.gitignore @@ -9,16 +9,8 @@ wheels/ # Virtual environments .venv -# Figures -notebooks/example_data/ -tests/figures/ - -# deployment site/ - -# ai agent docs IFLOW.md - *.bak .vscode/ diff --git a/src/plotfig/bar.py b/src/plotfig/bar.py index 3454d69..3e6302a 100644 --- a/src/plotfig/bar.py +++ b/src/plotfig/bar.py @@ -28,7 +28,6 @@ ] - def _is_valid_data(data): if isinstance(data, np.ndarray): return data.ndim == 2 @@ -225,6 +224,8 @@ def _statistics( statistical_line_color, asterisk_fontsize, asterisk_color, + y_base, + interval, ): if isinstance(test_method, list): if len(test_method) > 2 or ( @@ -240,7 +241,8 @@ def _statistics( return y_max = ax.get_ylim()[1] - interval = (y_max - np.max(all_values)) / (len(comparisons) + 1) + y_base = y_base or np.max(all_values) + interval = interval or (y_max - np.max(all_values)) / (len(comparisons) + 1) color = ( "b" @@ -251,7 +253,7 @@ def _statistics( _annotate_significance( ax, comparisons, - np.max(all_values), + y_base, interval, line_color=statistical_line_color, star_offset=interval / 5, @@ -269,11 +271,13 @@ def _statistics( return y_max = ax.get_ylim()[1] - interval = (y_max - np.max(all_values)) / (len(comparisons) + 1) + y_base = y_base or np.max(all_values) + interval = interval or (y_max - np.max(all_values)) / (len(comparisons) + 1) + _annotate_significance( ax, comparisons, - np.max(all_values), + y_base, interval, line_color=statistical_line_color, star_offset=interval / 5, @@ -293,7 +297,6 @@ def plot_one_group_bar_figure( colors_end: list[str] | None = None, show_dots: bool = True, dots_color: list[list[str]] | None = None, - y_lim: list[Num] | tuple[Num, Num] | None = None, width: Num = 0.5, color_alpha: Num = 1, dots_size: Num = 35, @@ -310,6 +313,7 @@ def plot_one_group_bar_figure( y_label_fontsize: Num = 10, y_tick_fontsize: Num = 8, y_tick_rotation: Num = 0, + y_lim: list[Num] | tuple[Num, Num] | None = None, statistic: bool = False, test_method: list[str] = ["ttest_ind"], p_list: list[float] | None = None, @@ -317,6 +321,8 @@ def plot_one_group_bar_figure( statistical_line_color: str = "0.5", asterisk_fontsize: Num = 10, asterisk_color: str = "k", + y_base: float | None = None, + interval: float | None = None, ax_bottom_is_0: bool = False, y_max_tick_is_1: bool = False, math_text: bool = True, @@ -346,8 +352,6 @@ def plot_one_group_bar_figure( 是否显示散点. Defaults to True. dots_color (list[list[str]] | None, optional): 散点的颜色列表. Defaults to None. - y_lim (list[Num] | tuple[Num, Num] | None, optional): - Y轴的范围限制. Defaults to None. width (Num, optional): 柱状图的宽度. Defaults to 0.5. color_alpha (Num, optional): @@ -380,6 +384,8 @@ def plot_one_group_bar_figure( Y轴刻度字体大小. Defaults to 8. y_tick_rotation (Num, optional): Y轴刻度旋转角度. Defaults to 0. + y_lim (list[Num] | tuple[Num, Num] | None, optional): + Y轴的范围限制. Defaults to None. statistic (bool, optional): 是否进行统计显著性分析. Defaults to False. test_method (list[str], optional): @@ -400,6 +406,10 @@ def plot_one_group_bar_figure( 显著性星号的字体大小. Defaults to 10. asterisk_color (str, optional): 显著性星号的颜色. Defaults to "k". + y_base (float | None, optional): + 显著性连线的起始Y轴位置(高度)。如果为None,则使用内部算法自动计算一个合适的位置。Defaults to None. + interval (float | None, optional): + 相邻显著性连线之间的垂直距离(Y轴增量)。如果为None,则使用内部算法根据图表范围和比较对数自动计算。Defaults to None. ax_bottom_is_0 (bool, optional): Y轴是否从0开始. Defaults to False. y_max_tick_is_1 (bool, optional): @@ -549,6 +559,8 @@ def plot_one_group_bar_figure( statistical_line_color, asterisk_fontsize, asterisk_color, + y_base, + interval, ) return ax @@ -577,6 +589,7 @@ def plot_one_group_violin_figure( y_label_fontsize: Num = 10, y_tick_fontsize: Num = 8, y_tick_rotation: Num = 0, + y_lim: list[Num] | tuple[Num, Num] | None = None, statistic: bool = False, test_method: list[str] = ["ttest_ind"], popmean: Num = 0, @@ -584,7 +597,8 @@ def plot_one_group_violin_figure( statistical_line_color: str = "0.5", asterisk_fontsize: Num = 10, asterisk_color: str = "k", - y_lim: list[Num] | tuple[Num, Num] | None = None, + y_base: float | None = None, + interval: float | None = None, ax_bottom_is_0: bool = False, y_max_tick_is_1: bool = False, math_text: bool = True, @@ -640,6 +654,8 @@ def plot_one_group_violin_figure( Y轴刻度字体大小. Defaults to 8. y_tick_rotation (Num, optional): Y轴刻度旋转角度. Defaults to 0. + y_lim (list[Num] | tuple[Num, Num] | None, optional): + Y轴的范围限制. Defaults to None. statistic (bool, optional): 是否进行统计显著性分析. Defaults to False. test_method (list[str], optional): @@ -654,8 +670,10 @@ def plot_one_group_violin_figure( 显著性星号的字体大小. Defaults to 10. asterisk_color (str, optional): 显著性星号的颜色. Defaults to "k". - y_lim (list[Num] | tuple[Num, Num] | None, optional): - Y轴的范围限制. Defaults to None. + y_base (float | None, optional): + 显著性连线的起始Y轴位置(高度)。如果为None,则使用内部算法自动计算一个合适的位置。Defaults to None. + interval (float | None, optional): + 相邻显著性连线之间的垂直距离(Y轴增量)。如果为None,则使用内部算法根据图表范围和比较对数自动计算。Defaults to None. ax_bottom_is_0 (bool, optional): Y轴是否从0开始. Defaults to False. y_max_tick_is_1 (bool, optional): @@ -830,6 +848,8 @@ def _draw_gradient_violin(ax, data, pos, width, c1, c2, color_alpha): statistical_line_color, asterisk_fontsize, asterisk_color, + y_base, + interval, ) return ax @@ -860,13 +880,15 @@ def plot_multi_group_bar_figure( y_label_fontsize=10, y_tick_fontsize=8, y_tick_rotation=0, + y_lim: list[Num] | tuple[Num, Num] | None = None, statistic: bool = False, test_method: str = "external", p_list: list[list[Num]] | None = None, line_color="0.5", asterisk_fontsize=10, asterisk_color="k", - y_lim: list[Num] | tuple[Num, Num] | None = None, + y_base: float | None = None, + interval: float | None = None, ax_bottom_is_0: bool = False, y_max_tick_is_1: bool = False, math_text: bool = True, @@ -924,6 +946,8 @@ def plot_multi_group_bar_figure( Y轴刻度字体大小. Defaults to 8. y_tick_rotation (int, optional): Y轴刻度旋转角度. Defaults to 0. + y_lim (list[Num] | tuple[Num, Num] | None, optional): + Y轴的范围限制. Defaults to None. statistic (bool, optional): 是否进行统计显著性分析. Defaults to False. test_method (str, optional): @@ -936,8 +960,10 @@ def plot_multi_group_bar_figure( 显著性星号的字体大小. Defaults to 10. asterisk_color (str, optional): 显著性星号的颜色. Defaults to "k". - y_lim (list[Num] | tuple[Num, Num] | None, optional): - Y轴的范围限制. Defaults to None. + y_base (float | None, optional): + 显著性连线的起始Y轴位置(高度)。如果为None,则使用内部算法自动计算一个合适的位置。Defaults to None. + interval (float | None, optional): + 相邻显著性连线之间的垂直距离(Y轴增量)。如果为None,则使用内部算法根据图表范围和比较对数自动计算。Defaults to None. ax_bottom_is_0 (bool, optional): Y轴是否从0开始. Defaults to False. y_max_tick_is_1 (bool, optional): @@ -1067,11 +1093,13 @@ def plot_multi_group_bar_figure( if p <= 0.05: comparisons.append((x_positions[i], x_positions[j], p)) y_max = ax.get_ylim()[1] - interval = (y_max - np.max(all_values)) / (len(comparisons) + 1) + y_base = y_base or np.max(all_values) + interval = interval or (y_max - np.max(all_values)) / (len(comparisons) + 1) + _annotate_significance( ax, comparisons, - np.max(all_values), + y_base, interval, line_color=line_color, star_offset=interval / 5, diff --git a/tests/test.ipynb b/tests/test.ipynb deleted file mode 100644 index bda3ed1..0000000 --- a/tests/test.ipynb +++ /dev/null @@ -1,53 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 5, - "id": "200d6161", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import numpy as np\n", - "from plotfig import plot_correlation_figure\n", - "\n", - "np.random.seed(42)\n", - "data1 = np.random.randn(100)\n", - "data2 = data1 + np.random.randn(100)\n", - "\n", - "ax = plot_correlation_figure(data1, data2)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "plotfig (3.11.11)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.11" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/zensical.toml b/zensical.toml index 3b76299..130939d 100644 --- a/zensical.toml +++ b/zensical.toml @@ -1,53 +1,14 @@ -# ============================================================================ -# -# The configuration produced by default is meant to highlight the features -# that Zensical provides and to serve as a starting point for your own -# projects. -# -# ============================================================================ - [project] - -# The site_name is shown in the page header and the browser window title -# -# Read more: https://zensical.org/docs/setup/basics/#site_name site_name = "plotfig" - -# The site_description is included in the HTML head and should contain a -# meaningful description of the site content for use by search engines. -# -# Read more: https://zensical.org/docs/setup/basics/#site_description site_description = "一个用于认知神经领域科研绘图的python包。" - -# The site_author attribute. This is used in the HTML head element. -# -# Read more: https://zensical.org/docs/setup/basics/#site_author site_author = "Ricardo Ryn" - -# The site_url is the canonical URL for your site. When building online -# documentation you should set this. -# Read more: https://zensical.org/docs/setup/basics/#site_url site_url = "https://ricardoryn.github.io/plotfig" repo_url = "https://github.com/RicardoRyn/plotfig" repo_name = "RicardoRyn/plotfig" edit_uri = "edit/main/docs/" - -# The copyright notice appears in the page footer and can contain an HTML -# fragment. -# -# Read more: https://zensical.org/docs/setup/basics/#copyright copyright = """ Copyright © 2025 Ricardo Ryn """ - -# Zensical supports both implicit navigation and explicitly defined navigation. -# If you decide not to define a navigation here then Zensical will simply -# derive the navigation structure from the directory structure of your -# "docs_dir". The definition below demonstrates how a navigation structure -# can be defined using TOML syntax. - -# -# Read more: https://zensical.org/docs/setup/navigation/ nav = [ { "🧭 简介" = "index.md" }, { "📦 安装" = "installation.md" }, @@ -64,214 +25,40 @@ nav = [ { "🔌 API" = "api/index.md" } ] -# With the "extra_css" option you can add your own CSS styling to customize -# your Zensical project according to your needs. You can add any number of -# CSS files. -# -# The path provided should be relative to the "docs_dir". -# -# Read more: https://zensical.org/docs/customization/#additional-css -# -#extra_css = ["assets/stylesheets/extra.css"] - -# With the `extra_javascript` option you can add your own JavaScript to your -# project to customize the behavior according to your needs. -# -# The path provided should be relative to the "docs_dir". -# -# Read more: https://zensical.org/docs/customization/#additional-javascript -#extra_javascript = ["assets/javascript/extra.js"] - -# ---------------------------------------------------------------------------- -# Section for configuring theme options -# ---------------------------------------------------------------------------- [project.theme] - -# change this to "classic" to use the traditional Material for MkDocs look. # variant = "classic" - -# Zensical allows you to override specific blocks, partials, or whole -# templates as well as to define your own templates. To do this, uncomment -# the custom_dir setting below and set it to a directory in which you -# keep your template overrides. -# -# Read more: -# - https://zensical.org/docs/customization/#extending-the-theme -# -#custom_dir = "overrides" - -# With the "favicon" option you can set your own image to use as the icon -# browsers will use in the browser title bar or tab bar. The path provided -# must be relative to the "docs_dir". -# -# Read more: -# - https://zensical.org/docs/setup/logo-and-icons/#favicon -# - https://developer.mozilla.org/en-US/docs/Glossary/Favicon -# -#favicon = "assets/images/favicon.png" - -# Zensical supports more than 60 different languages. This means that the -# labels and tooltips that Zensical's templates produce are translated. -# The "language" option allows you to set the language used. This language -# is also indicated in the HTML head element to help with accessibility -# and guide search engines and translation tools. -# -# The default language is "en" (English). It is possible to create -# sites with multiple languages and configure a language selector. See -# the documentation for details. -# -# Read more: -# - https://zensical.org/docs/setup/language/ -# +# custom_dir = "overrides" +# favicon = "assets/images/favicon.png" language = "zh" - -# Zensical provides a number of feature toggles that change the behavior -# of the documentation site. features = [ - # Zensical includes an announcement bar. This feature allows users to - # dismiss it then they have read the announcement. - # https://zensical.org/docs/setup/header/#announcement-bar "announce.dismiss", - - # If you have a repository configured and turn feature this on, Zensical - # will generate an edit button for the page. This works for common - # repository hosting services. - # https://zensical.org/docs/setup/repository/#code-actions "content.action.edit", - - # If you have a repository configured and turn feature this on, Zensical - # will generate a button that allows the user to view the Markdown - # code for the current page. - # https://zensical.org/docs/setup/repository/#code-actions "content.action.view", - - # Code annotations allow you to add an icon with a tooltip to your - # code blocks to provide explanations at crucial points. - # https://zensical.org/docs/authoring/code-blocks/#code-annotations "content.code.annotate", - - # This feature turns on a button in code blocks that allow users to - # copy the content to their clipboard without first selecting it. - # https://zensical.org/docs/authoring/code-blocks/#code-copy-button "content.code.copy", - - # Code blocks can include a button to allow for the selection of line - # ranges by the user. - # https://zensical.org/docs/authoring/code-blocks/#code-selection-button "content.code.select", - - # Zensical can render footnotes as inline tooltips, so the user can read - # the footnote without leaving the context of the document. - # https://zensical.org/docs/authoring/footnotes/#footnote-tooltips "content.footnote.tooltips", - - # If you have many content tabs that have the same titles (e.g., "Python", - # "JavaScript", "Cobol"), this feature causes all of them to switch to - # at the same time when the user chooses their language in one. - # https://zensical.org/docs/authoring/content-tabs/#linked-content-tabs "content.tabs.link", - - # TODO: not sure I understand this one? Is there a demo of this in the docs? - # https://zensical.org/docs/authoring/tooltips/#improved-tooltips "content.tooltips", - - # With this feature enabled, Zensical will automatically hide parts - # of the header when the user scrolls past a certain point. - # https://zensical.org/docs/setup/header/#automatic-hiding # "header.autohide", - - # Turn on this feature to expand all collapsible sections in the - # navigation sidebar by default. - # https://zensical.org/docs/setup/navigation/#navigation-expansion "navigation.expand", - - # This feature turns on navigation elements in the footer that allow the - # user to navigate to a next or previous page. - # https://zensical.org/docs/setup/footer/#navigation "navigation.footer", - - # When section index pages are enabled, documents can be directly attached - # to sections, which is particularly useful for providing overview pages. - # https://zensical.org/docs/setup/navigation/#section-index-pages "navigation.indexes", - - # When instant navigation is enabled, clicks on all internal links will be - # intercepted and dispatched via XHR without fully reloading the page. - # https://zensical.org/docs/setup/navigation/#instant-navigation "navigation.instant", - - # With instant prefetching, your site will start to fetch a page once the - # user hovers over a link. This will reduce the perceived loading time - # for the user. - # https://zensical.org/docs/setup/navigation/#instant-prefetching "navigation.instant.prefetch", - - # In order to provide a better user experience on slow connections when - # using instant navigation, a progress indicator can be enabled. - # https://zensical.org/docs/setup/navigation/#progress-indicator - #"navigation.instant.progress", - - # When navigation paths are activated, a breadcrumb navigation is rendered - # above the title of each page - # https://zensical.org/docs/setup/navigation/#navigation-path + # "navigation.instant.progress", # "navigation.path", - - # When pruning is enabled, only the visible navigation items are included - # in the rendered HTML, reducing the size of the built site by 33% or more. - # https://zensical.org/docs/setup/navigation/#navigation-pruning # "navigation.prune", - - # When sections are enabled, top-level sections are rendered as groups in - # the sidebar for viewports above 1220px, but remain as-is on mobile. - # https://zensical.org/docs/setup/navigation/#navigation-sections # "navigation.sections", - - # When tabs are enabled, top-level sections are rendered in a menu layer - # below the header for viewports above 1220px, but remain as-is on mobile. - # https://zensical.org/docs/setup/navigation/#navigation-tabs # "navigation.tabs", - - # When sticky tabs are enabled, navigation tabs will lock below the header - # and always remain visible when scrolling down. - # https://zensical.org/docs/setup/navigation/#sticky-navigation-tabs # "navigation.tabs.sticky", - - # A back-to-top button can be shown when the user, after scrolling down, - # starts to scroll up again. - # https://zensical.org/docs/setup/navigation/#back-to-top-button "navigation.top", - - # When anchor tracking is enabled, the URL in the address bar is - # automatically updated with the active anchor as highlighted in the table - # of contents. - # https://zensical.org/docs/setup/navigation/#anchor-tracking "navigation.tracking", - - # When search highlighting is enabled and a user clicks on a search result, - # Zensical will highlight all occurrences after following the link. - # https://zensical.org/docs/setup/search/#search-highlighting "search.highlight", - - # When anchor following for the table of contents is enabled, the sidebar - # is automatically scrolled so that the active anchor is always visible. - # https://zensical.org/docs/setup/navigation/#anchor-following # "toc.follow", - - # When navigation integration for the table of contents is enabled, it is - # always rendered as part of the navigation sidebar on the left. - # https://zensical.org/docs/setup/navigation/#navigation-integration #"toc.integrate", ] -# ---------------------------------------------------------------------------- -# In the "palette" subsection you can configure options for the color scheme. -# You can configure different color # schemes, e.g., to turn on dark mode, -# that the user can switch between. Each color scheme can be further -# customized. -# -# Read more: -# - https://zensical.org/docs/setup/colors/ -# ---------------------------------------------------------------------------- # Palette toggle for automatic mode [[project.theme.palette]] media = "(prefers-color-scheme)" @@ -292,40 +79,16 @@ scheme = "slate" toggle.icon = "lucide/moon" toggle.name = "Switch to system preference" -# ---------------------------------------------------------------------------- -# In the "font" subsection you can configure the fonts used. By default, fonts -# are loaded from Google Fonts, giving you a wide range of choices from a set -# of suitably licensed fonts. There are options for a normal text font and for -# a monospaced font used in code blocks. -# ---------------------------------------------------------------------------- -#[project.theme.font] -#text = "Inter" -#code = "Jetbrains Mono" +# [project.theme.font] +# text = "Inter" +# code = "Jetbrains Mono" -# ---------------------------------------------------------------------------- -# You can configure your own logo to be shown in the header using the "logo" -# option in the "icons" subsection. The logo can be a path to a file in your -# "docs_dir" or it can be a path to an icon. -# -# Likewise, you can customize the logo used for the repository section of the -# header. Zensical derives the default logo for this from the repository URL. -# See below... -# -# There are other icons you can customize. See the documentation for details. -# -# Read more: -# - https://zensical.org/docs/setup/logo-and-icons -# - https://zensical.org/docs/authoring/icons-emojis/#search -# ---------------------------------------------------------------------------- [project.theme.icon] # logo = "lucide/smile" # repo = "lucide/smile" edit = "material/pencil" view = "material/eye" -# ---------------------------------------------------------------------------- -# The "extra" section contains miscellaneous settings. -# ---------------------------------------------------------------------------- [[project.extra.social]] icon = "fontawesome/brands/github" link = "https://github.com/RicardoRyn"