1#----------------------------------------------------------------------------- 2# Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors. 3# All rights reserved. 4# 5# The full license is in the file LICENSE.txt, distributed with this software. 6#----------------------------------------------------------------------------- 7 8#----------------------------------------------------------------------------- 9# Boilerplate 10#----------------------------------------------------------------------------- 11import pytest ; pytest 12 13#----------------------------------------------------------------------------- 14# Imports 15#----------------------------------------------------------------------------- 16 17# Standard library imports 18import datetime 19 20# External imports 21import numpy as np 22 23# Bokeh imports 24from bokeh.models import ( 25 CategoricalAxis, 26 CategoricalScale, 27 DataRange1d, 28 DatetimeAxis, 29 FactorRange, 30 LinearAxis, 31 LinearScale, 32 LogAxis, 33 LogScale, 34 MercatorAxis, 35 Range1d, 36) 37 38# Module under test 39import bokeh.plotting._plot as bpp # isort:skip 40 41#----------------------------------------------------------------------------- 42# Setup 43#----------------------------------------------------------------------------- 44 45#----------------------------------------------------------------------------- 46# General API 47#----------------------------------------------------------------------------- 48 49#----------------------------------------------------------------------------- 50# Dev API 51#----------------------------------------------------------------------------- 52 53 54class test_get_scale_factor_range: 55 def test_numeric_range_linear_axis() -> None: 56 s = bpp.get_scale(Range1d(), "linear") 57 assert isinstance(s, LinearScale) 58 59 s = bpp.get_scale(Range1d(), "datetime") 60 assert isinstance(s, LinearScale) 61 62 s = bpp.get_scale(Range1d(), "auto") 63 assert isinstance(s, LinearScale) 64 65 def test_numeric_range_log_axis() -> None: 66 s = bpp.get_scale(DataRange1d(), "log") 67 assert isinstance(s, LogScale) 68 69 def test_factor_range() -> None: 70 s = bpp.get_scale(FactorRange(), "auto") 71 assert isinstance(s, CategoricalScale) 72 73 74class Test_get_range: 75 def test_with_None(self) -> None: 76 r = bpp.get_range(None) 77 assert isinstance(r, DataRange1d) 78 79 def test_with_Range(self) -> None: 80 for t in [Range1d, DataRange1d, FactorRange]: 81 rng = t() 82 r = bpp.get_range(rng) 83 assert r is rng 84 85 def test_with_ndarray(self) -> None: 86 r = bpp.get_range(np.array([10, 20])) 87 assert isinstance(r, Range1d) 88 assert r.start == 10 89 assert r.end == 20 90 91 def test_with_too_long_ndarray(self) -> None: 92 with pytest.raises(ValueError): 93 bpp.get_range(np.array([10, 20, 30])) 94 95 def test_with_ndarray_factors(self) -> None: 96 f = np.array(["Crosby", "Stills", "Nash", "Young"]) 97 r = bpp.get_range(f) 98 assert isinstance(r, FactorRange) 99 assert r.factors == list(f) 100 101 def test_with_series(self, pd) -> None: 102 r = bpp.get_range(pd.Series([20, 30])) 103 assert isinstance(r, Range1d) 104 assert r.start == 20 105 assert r.end == 30 106 107 def test_with_too_long_series(self, pd) -> None: 108 with pytest.raises(ValueError): 109 bpp.get_range(pd.Series([20, 30, 40])) 110 111 def test_with_string_seq(self) -> None: 112 f = ["foo" ,"end", "baz"] 113 for t in [list, tuple]: 114 r = bpp.get_range(t(f)) 115 assert isinstance(r, FactorRange) 116 # FactorRange accepts Seq, but get_range always sets a list copy 117 assert r.factors == f 118 119 def test_with_float_bounds(self) -> None: 120 r = bpp.get_range((1.2, 10)) 121 assert isinstance(r, Range1d) 122 assert r.start == 1.2 123 assert r.end == 10 124 125 r = bpp.get_range([1.2, 10]) 126 assert isinstance(r, Range1d) 127 assert r.start == 1.2 128 assert r.end == 10 129 130 def test_with_pandas_group(self, pd) -> None: 131 from bokeh.sampledata.iris import flowers 132 g = flowers.groupby('species') 133 r = bpp.get_range(g) 134 assert isinstance(r, FactorRange) 135 assert r.factors == ['setosa', 'versicolor', 'virginica'] # should always be sorted 136 137#----------------------------------------------------------------------------- 138# Private API 139#----------------------------------------------------------------------------- 140 141_RANGES = [Range1d(), DataRange1d(), FactorRange()] 142 143 144class Test__get_axis_class: 145 @pytest.mark.parametrize('range', _RANGES) 146 def test_axis_type_None(self, range) -> None: 147 assert(bpp._get_axis_class(None, range, 0)) == (None, {}) 148 assert(bpp._get_axis_class(None, range, 1)) == (None, {}) 149 150 @pytest.mark.parametrize('range', _RANGES) 151 def test_axis_type_linear(self, range) -> None: 152 assert(bpp._get_axis_class("linear", range, 0)) == (LinearAxis, {}) 153 assert(bpp._get_axis_class("linear", range, 1)) == (LinearAxis, {}) 154 155 @pytest.mark.parametrize('range', _RANGES) 156 def test_axis_type_log(self, range) -> None: 157 assert(bpp._get_axis_class("log", range, 0)) == (LogAxis, {}) 158 assert(bpp._get_axis_class("log", range, 1)) == (LogAxis, {}) 159 160 @pytest.mark.parametrize('range', _RANGES) 161 def test_axis_type_datetime(self, range) -> None: 162 assert(bpp._get_axis_class("datetime", range, 0)) == (DatetimeAxis, {}) 163 assert(bpp._get_axis_class("datetime", range, 1)) == (DatetimeAxis, {}) 164 165 @pytest.mark.parametrize('range', _RANGES) 166 def test_axis_type_mercator(self, range) -> None: 167 assert(bpp._get_axis_class("mercator", range, 0)) == (MercatorAxis, {'dimension': 'lon'}) 168 assert(bpp._get_axis_class("mercator", range, 1)) == (MercatorAxis, {'dimension': 'lat'}) 169 170 def test_axis_type_auto(self) -> None: 171 assert(bpp._get_axis_class("auto", FactorRange(), 0)) == (CategoricalAxis, {}) 172 assert(bpp._get_axis_class("auto", FactorRange(), 1)) == (CategoricalAxis, {}) 173 assert(bpp._get_axis_class("auto", DataRange1d(), 0)) == (LinearAxis, {}) 174 assert(bpp._get_axis_class("auto", DataRange1d(), 1)) == (LinearAxis, {}) 175 assert(bpp._get_axis_class("auto", Range1d(), 0)) == (LinearAxis, {}) 176 assert(bpp._get_axis_class("auto", Range1d(), 1)) == (LinearAxis, {}) 177 assert(bpp._get_axis_class("auto", Range1d(start=datetime.datetime(2018, 3, 21)), 0)) == (DatetimeAxis, {}) 178 assert(bpp._get_axis_class("auto", Range1d(start=datetime.datetime(2018, 3, 21)), 1)) == (DatetimeAxis, {}) 179 180 @pytest.mark.parametrize('range', _RANGES) 181 def test_axis_type_error(self, range) -> None: 182 with pytest.raises(ValueError): 183 bpp._get_axis_class("junk", range, 0) 184 with pytest.raises(ValueError): 185 bpp._get_axis_class("junk", range, 1) 186 187#----------------------------------------------------------------------------- 188# Code 189#----------------------------------------------------------------------------- 190