diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index a00b4d9..37a37ef 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -8,7 +8,10 @@ What's new in version 0.9
   shading of rows in the intersection matrix, and bars in the totals plot.
   (:issue:`261` with thanks to :user:`Marcel Albus <maralbus>`).
 - Ability to disable totals plot with `totals_plot_elements=0`. (:issue:`246`)
+- Ability to set totals y axis label (:issue:`243`)
 - Added ``max_subset_rank`` to get only n most populous subsets. (:issue:`253`)
+- Added support for ``min_subset_size`` and ``max_subset_size`` specified as
+  percentage. (:issue:`264`)
 
 What's new in version 0.8
 -------------------------
diff --git a/upsetplot/plotting.py b/upsetplot/plotting.py
index e2f50bd..3d5630f 100644
--- a/upsetplot/plotting.py
+++ b/upsetplot/plotting.py
@@ -191,17 +191,27 @@ class UpSet:
         If `subset_size='sum'` or `'auto'`, then the intersection size is the
         sum of the specified field in the `data` DataFrame. If a Series, only
         None is supported and its value is summed.
-    min_subset_size : int, optional
+    min_subset_size : int or "number%", optional
         Minimum size of a subset to be shown in the plot. All subsets with
         a size smaller than this threshold will be omitted from plotting.
+        This may be specified as a percentage
+        using a string, like "50%".
         Size may be a sum of values, see `subset_size`.
 
         .. versionadded:: 0.5
-    max_subset_size : int, optional
+
+        .. versionchanged:: 0.9
+            Support percentages
+    max_subset_size : int or "number%", optional
         Maximum size of a subset to be shown in the plot. All subsets with
         a size greater than this threshold will be omitted from plotting.
+        This may be specified as a percentage
+        using a string, like "50%".
 
         .. versionadded:: 0.5
+
+        .. versionchanged:: 0.9
+            Support percentages
     max_subset_rank : int, optional
         Limit to the top N ranked subsets in descending order of size.
         All tied subsets are included.
@@ -379,10 +389,18 @@ class UpSet:
         absent : str or list of str, optional
             Category or categories that must not be present in subsets for
             styling.
-        min_subset_size : int, optional
+        min_subset_size : int or "number%", optional
             Minimum size of a subset to be styled.
-        max_subset_size : int, optional
+            This may be specified as a percentage using a string, like "50%".
+
+            .. versionchanged:: 0.9
+                Support percentages
+        max_subset_size : int or "number%", optional
             Maximum size of a subset to be styled.
+            This may be specified as a percentage using a string, like "50%".
+
+            .. versionchanged:: 0.9
+                Support percentages
         max_subset_rank : int, optional
             Limit to the top N ranked subsets in descending order of size.
             All tied subsets are included.
diff --git a/upsetplot/reformat.py b/upsetplot/reformat.py
index 821a359..5853729 100644
--- a/upsetplot/reformat.py
+++ b/upsetplot/reformat.py
@@ -93,6 +93,19 @@ def _scalar_to_list(val):
     return val
 
 
+def _check_percent(value, agg):
+    if not isinstance(value, str):
+        return value
+    try:
+        if value.endswith("%") and 0 <= float(value[:-1]) <= 100:
+            return float(value[:-1]) / 100 * agg.sum()
+    except ValueError:
+        pass
+    raise ValueError(
+        f"String value must be formatted as percentage between 0 and 100. Got {value}"
+    )
+
+
 def _get_subset_mask(
     agg,
     min_subset_size,
@@ -104,6 +117,8 @@ def _get_subset_mask(
     absent,
 ):
     """Get a mask over subsets based on size, degree or category presence"""
+    min_subset_size = _check_percent(min_subset_size, agg)
+    max_subset_size = _check_percent(max_subset_size, agg)
     subset_mask = True
     if min_subset_size is not None:
         subset_mask = np.logical_and(subset_mask, agg >= min_subset_size)
@@ -235,13 +250,20 @@ def query(
     absent : str or list of str, optional
         Category or categories that must not be present in subsets for
         styling.
-    min_subset_size : int, optional
+    min_subset_size : int or "number%", optional
         Minimum size of a subset to be reported. All subsets with
         a size smaller than this threshold will be omitted from
-        category_totals and data.
+        category_totals and data.  This may be specified as a percentage
+        using a string, like "50%".
         Size may be a sum of values, see `subset_size`.
-    max_subset_size : int, optional
+
+        .. versionchanged:: 0.9
+            Support percentages
+    max_subset_size : int or "number%", optional
         Maximum size of a subset to be reported.
+
+        .. versionchanged:: 0.9
+            Support percentages
     max_subset_rank : int, optional
         Limit to the top N ranked subsets in descending order of size.
         All tied subsets are included.

diff --git a/upsetplot/tests/test_upsetplot.py b/upsetplot/tests/test_upsetplot.py
index d96b42d..3c33dea 100644
--- a/upsetplot/tests/test_upsetplot.py
+++ b/upsetplot/tests/test_upsetplot.py
@@ -768,6 +768,13 @@ def test_index_must_be_bool(x):
                 (True, True, True): 990,
             },
         ),
+        (
+            {"min_subset_size": "15%", "max_subset_size": "30.1%"},
+            {
+                (True, False, False): 884,
+                (True, True, True): 990,
+            },
+        ),
         (
             {"min_degree": 2},
             {
@@ -853,6 +860,22 @@ def test_filter_subsets_max_subset_rank_tie():
     assert cur.shape[0] == full.shape[0]
 
 
+@pytest.mark.parametrize(
+    "value",
+    [
+        "1",
+        "-1%",
+        "1%%",
+        "%1",
+        "hello",
+    ],
+)
+def test_bad_percentages(value):
+    data = generate_samples(seed=0, n_samples=5, n_categories=3)
+    with pytest.raises(ValueError, match="percentage"):
+        UpSet(data, min_subset_size=value)
+
+
 @pytest.mark.parametrize(
     "x",
     [

Express min_subset_size as a percentage / fraction
It should be possible to use `min_subset_size="30%"` and similar percentage specification of `max_subset_size`, corresponding to the values displayed with `show_percentages`.

From #170
upsetplot/tests/test_upsetplot.py::test_filter_subsets[cardinality-filter_params3-expected3] upsetplot/tests/test_upsetplot.py::test_filter_subsets[degree-filter_params3-expected3] upsetplot/tests/test_upsetplot.py::test_bad_percentages[1] upsetplot/tests/test_upsetplot.py::test_bad_percentages[-1%] upsetplot/tests/test_upsetplot.py::test_bad_percentages[1%%] upsetplot/tests/test_upsetplot.py::test_bad_percentages[%1] upsetplot/tests/test_upsetplot.py::test_bad_percentages[hello]
upsetplot/tests/test_upsetplot.py::test_process_data_series[None-cardinality-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[None-cardinality-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[None-degree-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[None-degree-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[None--cardinality-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[None--cardinality-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[None--degree-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[None--degree-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[None-None-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[None-None-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[None-input-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[None-input-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[None--input-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[None--input-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[input-cardinality-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[input-cardinality-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[input-degree-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[input-degree-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[input--cardinality-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[input--cardinality-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[input--degree-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[input--degree-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[input-None-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[input-None-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[input-input-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[input-input-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[input--input-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[input--input-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input-cardinality-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input-cardinality-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input-degree-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input-degree-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input--cardinality-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input--cardinality-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input--degree-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input--degree-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input-None-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input-None-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input-input-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input-input-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input--input-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-input--input-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality-cardinality-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality-cardinality-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality-degree-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality-degree-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality--cardinality-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality--cardinality-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality--degree-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality--degree-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality-None-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality-None-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality-input-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality-input-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality--input-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[cardinality--input-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality-cardinality-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality-cardinality-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality-degree-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality-degree-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality--cardinality-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality--cardinality-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality--degree-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality--degree-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality-None-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality-None-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality-input-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality-input-x1] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality--input-x0] upsetplot/tests/test_upsetplot.py::test_process_data_series[-cardinality--input-x1] upsetplot/tests/test_upsetplot.py::test_subset_size_series[x0] upsetplot/tests/test_upsetplot.py::test_subset_size_series[x1] upsetplot/tests/test_upsetplot.py::test_subset_size_frame[x0] upsetplot/tests/test_upsetplot.py::test_subset_size_frame[x1] upsetplot/tests/test_upsetplot.py::test_not_unique[None-cardinality] upsetplot/tests/test_upsetplot.py::test_not_unique[None-degree] upsetplot/tests/test_upsetplot.py::test_not_unique[cardinality-cardinality] upsetplot/tests/test_upsetplot.py::test_not_unique[cardinality-degree] upsetplot/tests/test_upsetplot.py::test_include_empty_subsets upsetplot/tests/test_upsetplot.py::test_param_validation[kw0] upsetplot/tests/test_upsetplot.py::test_param_validation[kw1] upsetplot/tests/test_upsetplot.py::test_param_validation[kw2] upsetplot/tests/test_upsetplot.py::test_param_validation[kw3] upsetplot/tests/test_upsetplot.py::test_plot_smoke_test[kw0] upsetplot/tests/test_upsetplot.py::test_plot_smoke_test[kw1] upsetplot/tests/test_upsetplot.py::test_plot_smoke_test[kw2] upsetplot/tests/test_upsetplot.py::test_plot_smoke_test[kw3] upsetplot/tests/test_upsetplot.py::test_plot_smoke_test[kw4] upsetplot/tests/test_upsetplot.py::test_plot_smoke_test[kw5] upsetplot/tests/test_upsetplot.py::test_plot_smoke_test[kw6] upsetplot/tests/test_upsetplot.py::test_two_sets[set20-set10] upsetplot/tests/test_upsetplot.py::test_two_sets[set20-set11] upsetplot/tests/test_upsetplot.py::test_two_sets[set20-set12] upsetplot/tests/test_upsetplot.py::test_two_sets[set20-set13] upsetplot/tests/test_upsetplot.py::test_two_sets[set21-set10] upsetplot/tests/test_upsetplot.py::test_two_sets[set21-set11] upsetplot/tests/test_upsetplot.py::test_two_sets[set21-set12] upsetplot/tests/test_upsetplot.py::test_two_sets[set21-set13] upsetplot/tests/test_upsetplot.py::test_two_sets[set22-set10] upsetplot/tests/test_upsetplot.py::test_two_sets[set22-set11] upsetplot/tests/test_upsetplot.py::test_two_sets[set22-set12] upsetplot/tests/test_upsetplot.py::test_two_sets[set22-set13] upsetplot/tests/test_upsetplot.py::test_two_sets[set23-set10] upsetplot/tests/test_upsetplot.py::test_two_sets[set23-set11] upsetplot/tests/test_upsetplot.py::test_two_sets[set23-set12] upsetplot/tests/test_upsetplot.py::test_two_sets[set23-set13] upsetplot/tests/test_upsetplot.py::test_vertical upsetplot/tests/test_upsetplot.py::test_element_size upsetplot/tests/test_upsetplot.py::test_show_counts[horizontal] upsetplot/tests/test_upsetplot.py::test_show_counts[vertical] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars[False-horizontal] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars[False-vertical] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars[True-horizontal] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars[True-vertical] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_colors[colors0-expected0] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_colors[colors1-expected1] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_colors[Pastel1-expected2] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_colors[colors3-expected3] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_colors[<lambda>-expected4] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_sum_over[False-False-False] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_sum_over[False-False-True] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_sum_over[False-True-False] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_sum_over[False-True-True] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_sum_over[True-False-False] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_sum_over[True-False-True] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_sum_over[True-True-False] upsetplot/tests/test_upsetplot.py::test_add_stacked_bars_sum_over[True-True-True] upsetplot/tests/test_upsetplot.py::test_index_must_be_bool[x0] upsetplot/tests/test_upsetplot.py::test_filter_subsets[cardinality-filter_params0-expected0] upsetplot/tests/test_upsetplot.py::test_filter_subsets[cardinality-filter_params1-expected1] upsetplot/tests/test_upsetplot.py::test_filter_subsets[cardinality-filter_params2-expected2] upsetplot/tests/test_upsetplot.py::test_filter_subsets[cardinality-filter_params4-expected4] upsetplot/tests/test_upsetplot.py::test_filter_subsets[cardinality-filter_params5-expected5] upsetplot/tests/test_upsetplot.py::test_filter_subsets[cardinality-filter_params6-expected6] upsetplot/tests/test_upsetplot.py::test_filter_subsets[degree-filter_params0-expected0] upsetplot/tests/test_upsetplot.py::test_filter_subsets[degree-filter_params1-expected1] upsetplot/tests/test_upsetplot.py::test_filter_subsets[degree-filter_params2-expected2] upsetplot/tests/test_upsetplot.py::test_filter_subsets[degree-filter_params4-expected4] upsetplot/tests/test_upsetplot.py::test_filter_subsets[degree-filter_params5-expected5] upsetplot/tests/test_upsetplot.py::test_filter_subsets[degree-filter_params6-expected6] upsetplot/tests/test_upsetplot.py::test_filter_subsets_max_subset_rank_tie upsetplot/tests/test_upsetplot.py::test_matrix_plot_margins[horizontal-x0] upsetplot/tests/test_upsetplot.py::test_matrix_plot_margins[horizontal-x1] upsetplot/tests/test_upsetplot.py::test_matrix_plot_margins[horizontal-x2] upsetplot/tests/test_upsetplot.py::test_matrix_plot_margins[vertical-x0] upsetplot/tests/test_upsetplot.py::test_matrix_plot_margins[vertical-x1] upsetplot/tests/test_upsetplot.py::test_matrix_plot_margins[vertical-x2] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list0-expected_subset_styles0-expected_legend0] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list1-expected_subset_styles1-expected_legend1] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list2-expected_subset_styles2-expected_legend2] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list3-expected_subset_styles3-expected_legend3] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list4-expected_subset_styles4-expected_legend4] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list5-expected_subset_styles5-expected_legend5] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list6-expected_subset_styles6-expected_legend6] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list7-expected_subset_styles7-expected_legend7] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list8-expected_subset_styles8-expected_legend8] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list9-expected_subset_styles9-expected_legend9] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list10-expected_subset_styles10-expected_legend10] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list11-expected_subset_styles11-expected_legend11] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list12-expected_subset_styles12-expected_legend12] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list13-expected_subset_styles13-expected_legend13] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list14-expected_subset_styles14-expected_legend14] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list15-expected_subset_styles15-expected_legend15] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list16-expected_subset_styles16-expected_legend16] upsetplot/tests/test_upsetplot.py::test_style_subsets[kwarg_list17-expected_subset_styles17-expected_legend17] upsetplot/tests/test_upsetplot.py::test_style_subsets_artists[horizontal] upsetplot/tests/test_upsetplot.py::test_style_subsets_artists[vertical] upsetplot/tests/test_upsetplot.py::test_categories[kwarg_list0-expected_category_styles0] upsetplot/tests/test_upsetplot.py::test_categories[kwarg_list1-expected_category_styles1] upsetplot/tests/test_upsetplot.py::test_categories[kwarg_list2-expected_category_styles2] upsetplot/tests/test_upsetplot.py::test_many_categories