sympy-plot-backends 2.0.2__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/PKG-INFO +1 -1
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/setup.py +1 -1
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/__init__.py +4 -6
- sympy_plot_backends-2.2.0/spb/_version.py +1 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/backends/base_backend.py +14 -18
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/backends/bokeh.py +77 -24
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/backends/k3d.py +20 -15
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/backends/matplotlib.py +105 -56
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/backends/plotly.py +92 -38
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/ccomplex/complex.py +546 -71
- sympy_plot_backends-2.2.0/spb/ccomplex/wegert.py +449 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/defaults.py +5 -4
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/functions.py +182 -101
- sympy_plot_backends-2.2.0/spb/plotgrid.py +376 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/series.py +214 -91
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/utils.py +24 -7
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/vectors.py +9 -12
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/sympy_plot_backends.egg-info/PKG-INFO +1 -1
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/backends/make_tests.py +63 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/backends/test_bokeh.py +104 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/backends/test_k3d.py +9 -1
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/backends/test_matplotlib.py +177 -1
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/backends/test_plotly.py +174 -3
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/test_complex.py +112 -2
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/test_functions.py +644 -5
- sympy_plot_backends-2.2.0/tests/test_plotgrid.py +326 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/test_series.py +89 -3
- sympy_plot_backends-2.2.0/tests/test_utils.py +167 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/test_vectors.py +35 -0
- sympy_plot_backends-2.0.2/spb/_version.py +0 -1
- sympy_plot_backends-2.0.2/spb/ccomplex/wegert.py +0 -281
- sympy_plot_backends-2.0.2/spb/plotgrid.py +0 -223
- sympy_plot_backends-2.0.2/tests/test_plotgrid.py +0 -221
- sympy_plot_backends-2.0.2/tests/test_utils.py +0 -623
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/LICENSE +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/MANIFEST.in +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/README.md +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/setup.cfg +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/backends/__init__.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/backends/mayavi.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/backends/utils.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/ccomplex/__init__.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/doc_utils.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/interactive/__init__.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/interactive/bootstrap_spb/__init__.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/interactive/bootstrap_spb/bootstrap.css +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/interactive/bootstrap_spb/bootstrap.html +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/interactive/bootstrap_spb/dark.css +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/interactive/ipywidgets.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/spb/interactive/panel.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/sympy_plot_backends.egg-info/SOURCES.txt +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/sympy_plot_backends.egg-info/dependency_links.txt +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/sympy_plot_backends.egg-info/not-zip-safe +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/sympy_plot_backends.egg-info/requires.txt +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/sympy_plot_backends.egg-info/top_level.txt +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/backends/__init__.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/backends/test_base_backend.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/test_color_utils.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/test_defaults.py +0 -0
- {sympy_plot_backends-2.0.2 → sympy_plot_backends-2.2.0}/tests/test_doc_utils.py +0 -0
|
@@ -20,14 +20,11 @@ from spb.functions import (
|
|
|
20
20
|
from spb.vectors import plot_vector
|
|
21
21
|
from spb.ccomplex.complex import (
|
|
22
22
|
plot_complex, plot_complex_list,
|
|
23
|
-
plot_real_imag, plot_complex_vector
|
|
23
|
+
plot_real_imag, plot_complex_vector, plot_riemann_sphere
|
|
24
24
|
)
|
|
25
25
|
from spb.utils import prange
|
|
26
26
|
|
|
27
|
-
from spb.plotgrid import plotgrid
|
|
28
|
-
# NOTE: it would be nice to have `iplot` readily available, however loading
|
|
29
|
-
# `panel` is a slow operation.
|
|
30
|
-
# from spb.interactive import iplot
|
|
27
|
+
from spb.plotgrid import plotgrid, PlotGrid
|
|
31
28
|
|
|
32
29
|
from spb.backends.matplotlib import MB
|
|
33
30
|
from spb.backends.bokeh import BB
|
|
@@ -42,5 +39,6 @@ __all__ = [
|
|
|
42
39
|
"plot3d_revolution", "plot_implicit", "plot_polar", "plot_geometry",
|
|
43
40
|
"plot_list", "plot_piecewise", "plot_vector", "plot_complex",
|
|
44
41
|
"plot_complex_list", "plot_real_imag", "plot_complex_vector", "plotgrid",
|
|
45
|
-
"MB", "BB", "PB", "KB", "MAB", "plot3d_list", "prange"
|
|
42
|
+
"MB", "BB", "PB", "KB", "MAB", "plot3d_list", "prange",
|
|
43
|
+
"plot_riemann_sphere", "PlotGrid"
|
|
46
44
|
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.2.0"
|
|
@@ -177,9 +177,9 @@ class Plot:
|
|
|
177
177
|
ranges over [-pi, pi]).
|
|
178
178
|
"""
|
|
179
179
|
|
|
180
|
-
_allowed_keys = ["aspect", "axis", "axis_center", "backend",
|
|
180
|
+
_allowed_keys = ["aspect", "axis", "axis_center", "backend", "aouc",
|
|
181
181
|
"detect_poles", "grid", "legend", "show", "size", "title", "use_latex",
|
|
182
|
-
"xlabel", "ylabel", "zlabel", "xlim", "ylim", "zlim",
|
|
182
|
+
"xlabel", "ylabel", "zlabel", "xlim", "ylim", "zlim", "show_axis",
|
|
183
183
|
"xscale", "yscale", "zscale", "process_piecewise", "polar_axis", "imodule"]
|
|
184
184
|
"""contains a list of public keyword arguments supported by the series.
|
|
185
185
|
It will be used to validate the user-provided keyword arguments.
|
|
@@ -249,6 +249,8 @@ class Plot:
|
|
|
249
249
|
# backend might need to create different types of figure depending on
|
|
250
250
|
# the interactive module being used
|
|
251
251
|
self.imodule = kwargs.get("imodule", None)
|
|
252
|
+
# add annotations on unit circle in the complex plane.
|
|
253
|
+
self.aouc = kwargs.get("aouc", None)
|
|
252
254
|
|
|
253
255
|
# Contains the data objects to be plotted. The backend should be smart
|
|
254
256
|
# enough to iterate over this list.
|
|
@@ -269,18 +271,15 @@ class Plot:
|
|
|
269
271
|
# Automatic legend: if more than 1 data series has been provided
|
|
270
272
|
# and the user has not set legend=False, then show the legend for
|
|
271
273
|
# better clarity.
|
|
272
|
-
self.legend =
|
|
273
|
-
if
|
|
274
|
-
self.
|
|
275
|
-
if
|
|
276
|
-
|
|
274
|
+
self.legend = kwargs.get("legend", None)
|
|
275
|
+
if self.legend is None:
|
|
276
|
+
# if len([s for s in self._series if s.show_in_legend]) > 1:
|
|
277
|
+
if len([s for s in self._series
|
|
278
|
+
if s.show_in_legend and (not s.use_cm)]) > 1:
|
|
277
279
|
# don't show the legend if `plot_piecewise` created this
|
|
278
280
|
# backend
|
|
279
|
-
if
|
|
280
|
-
((_legend is True) or (_legend is None))):
|
|
281
|
+
if not ("process_piecewise" in kwargs.keys()):
|
|
281
282
|
self.legend = True
|
|
282
|
-
if self.legend and (len([s for s in self._series if s.is_3Dsurface and not s.use_cm]) > 1):
|
|
283
|
-
self.legend = False
|
|
284
283
|
|
|
285
284
|
# Objects used to render/display the plots, which depends on the
|
|
286
285
|
# plotting library.
|
|
@@ -308,6 +307,7 @@ class Plot:
|
|
|
308
307
|
check_and_set("zlim", kwargs.get("zlim", None))
|
|
309
308
|
self.size = None
|
|
310
309
|
check_and_set("size", kwargs.get("size", None))
|
|
310
|
+
self.show_axis = kwargs.get("show_axis", True)
|
|
311
311
|
|
|
312
312
|
def _copy_kwargs(self):
|
|
313
313
|
"""Copy the values of the plot attributes into a dictionary which will
|
|
@@ -333,7 +333,9 @@ class Plot:
|
|
|
333
333
|
is_iplot=self.is_iplot,
|
|
334
334
|
use_latex=self._use_latex,
|
|
335
335
|
camera=self.camera,
|
|
336
|
-
polar_axis=self.polar_axis
|
|
336
|
+
polar_axis=self.polar_axis,
|
|
337
|
+
aouc=self.aouc,
|
|
338
|
+
show_axis=self.show_axis,
|
|
337
339
|
)
|
|
338
340
|
|
|
339
341
|
def _init_cyclers(self):
|
|
@@ -476,12 +478,6 @@ class Plot:
|
|
|
476
478
|
series.extend(self.series)
|
|
477
479
|
series.extend(other.series)
|
|
478
480
|
kwargs = self._do_sum_kwargs(self, other)
|
|
479
|
-
# If the first plot (`p1`) of the summation has been created without
|
|
480
|
-
# specifying `legend`, then `p1.legend` might be False, hence
|
|
481
|
-
# `kwargs["legend"]` might be False. But when adding multiple plots
|
|
482
|
-
# it is very likely that user expect a legend to be shown. Hence,
|
|
483
|
-
# reset legend and let the backend decide if it needs one or not.
|
|
484
|
-
kwargs["legend"] = None
|
|
485
481
|
return type(self)(*series, **kwargs)
|
|
486
482
|
|
|
487
483
|
def append(self, arg):
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from spb.defaults import cfg
|
|
3
3
|
from spb.backends.base_backend import Plot
|
|
4
|
+
from spb.series import GenericDataSeries, List2DSeries
|
|
4
5
|
from sympy.external import import_module
|
|
5
6
|
import warnings
|
|
6
7
|
|
|
@@ -214,6 +215,10 @@ class BokehBackend(Plot):
|
|
|
214
215
|
* Default options for streamline plots:
|
|
215
216
|
``dict(line_width=2, line_alpha=0.8)``
|
|
216
217
|
|
|
218
|
+
show_axis : boolean, optional
|
|
219
|
+
Turns on/off the axis visibility (and associated tick labels).
|
|
220
|
+
Default to True (axis are visible).
|
|
221
|
+
|
|
217
222
|
theme : str, optional
|
|
218
223
|
Set the theme. Find more Bokeh themes at [#fn2]_ .
|
|
219
224
|
|
|
@@ -349,6 +354,7 @@ class BokehBackend(Plot):
|
|
|
349
354
|
if self.ylim:
|
|
350
355
|
kw["y_range"] = self.ylim
|
|
351
356
|
self._fig = self.bokeh.plotting.figure(**kw)
|
|
357
|
+
self._fig.axis.visible = self.show_axis
|
|
352
358
|
self.grid = kwargs.get("grid", cfg["bokeh"]["grid"])
|
|
353
359
|
self._fig.grid.visible = self.grid
|
|
354
360
|
if cfg["bokeh"]["show_minor_grid"]:
|
|
@@ -356,6 +362,33 @@ class BokehBackend(Plot):
|
|
|
356
362
|
self._fig.grid.minor_grid_line_color = self._fig.grid.grid_line_color[0]
|
|
357
363
|
self._fig.grid.minor_grid_line_dash = cfg["bokeh"]["minor_grid_line_dash"]
|
|
358
364
|
|
|
365
|
+
if self.aouc:
|
|
366
|
+
pixel_offset = 15
|
|
367
|
+
# assumption: there is only one data series being plotted.
|
|
368
|
+
sign = 1
|
|
369
|
+
labels = ["0", "i", "-i", "1"]
|
|
370
|
+
if self.series[0].at_infinity:
|
|
371
|
+
labels[0] = "inf"
|
|
372
|
+
sign = -1
|
|
373
|
+
source = self.bokeh.models.ColumnDataSource(data={
|
|
374
|
+
"x": [0, 0, 0, 1], "y": [0, 1, -1, 0], "labels": labels,
|
|
375
|
+
"x_offset": [pixel_offset, 0, 0, sign * pixel_offset],
|
|
376
|
+
"y_offset": [0, pixel_offset, -pixel_offset, 0]
|
|
377
|
+
})
|
|
378
|
+
new_series = [
|
|
379
|
+
List2DSeries([1, 0, 0], [0, 1, -1], is_point=True,
|
|
380
|
+
is_filled=False, show_in_legend=False,
|
|
381
|
+
rendering_kw={"color": "#000000", "marker": "circle", "size": 6}),
|
|
382
|
+
List2DSeries([0], [0], is_point=True,
|
|
383
|
+
is_filled=(not self.series[0].at_infinity), show_in_legend=False,
|
|
384
|
+
rendering_kw={"color": "#000000", "marker": "circle", "size": 6}),
|
|
385
|
+
GenericDataSeries("annotations", x="x", y="y", text="labels",
|
|
386
|
+
x_offset="x_offset", y_offset="y_offset", source=source,
|
|
387
|
+
text_baseline="middle", text_align="center",
|
|
388
|
+
text_font_style="bold", text_color="#000000"),
|
|
389
|
+
]
|
|
390
|
+
self._series = self._series + new_series
|
|
391
|
+
|
|
359
392
|
@property
|
|
360
393
|
def fig(self):
|
|
361
394
|
"""Returns the figure."""
|
|
@@ -408,7 +441,7 @@ class BokehBackend(Plot):
|
|
|
408
441
|
x, y, param, colormap, s.get_label(self._use_latex),
|
|
409
442
|
s.rendering_kw, s.is_point)
|
|
410
443
|
self._fig.add_glyph(ds, line)
|
|
411
|
-
if
|
|
444
|
+
if s.colorbar:
|
|
412
445
|
self._handles[i] = cb
|
|
413
446
|
self._fig.add_layout(cb, "right")
|
|
414
447
|
else:
|
|
@@ -422,10 +455,12 @@ class BokehBackend(Plot):
|
|
|
422
455
|
"ys": y if not s.is_polar else y * np.sin(x)
|
|
423
456
|
}
|
|
424
457
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
color=
|
|
458
|
+
if s.get_label(False) != "__k__":
|
|
459
|
+
color = next(self._cl) if s.line_color is None else s.line_color
|
|
460
|
+
else:
|
|
461
|
+
color = "#000000"
|
|
462
|
+
lkw = dict(line_width=2, color=color,
|
|
463
|
+
legend_label=s.get_label(self._use_latex))
|
|
429
464
|
if not s.is_point:
|
|
430
465
|
kw = merge({}, lkw, s.rendering_kw)
|
|
431
466
|
self._fig.line("xs", "ys", source=source, **kw)
|
|
@@ -461,13 +496,14 @@ class BokehBackend(Plot):
|
|
|
461
496
|
**kw
|
|
462
497
|
)
|
|
463
498
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
499
|
+
if s.colorbar:
|
|
500
|
+
colormapper = self.bokeh.models.LinearColorMapper(
|
|
501
|
+
palette=cm, low=minz, high=maxz)
|
|
502
|
+
cbkw = dict(width=8, title=s.get_label(self._use_latex))
|
|
503
|
+
colorbar = self.bokeh.models.ColorBar(
|
|
504
|
+
color_mapper=colormapper, **cbkw)
|
|
505
|
+
self._fig.add_layout(colorbar, "right")
|
|
506
|
+
self._handles[i] = colorbar
|
|
471
507
|
|
|
472
508
|
elif s.is_2Dvector:
|
|
473
509
|
if s.is_streamlines:
|
|
@@ -509,7 +545,7 @@ class BokehBackend(Plot):
|
|
|
509
545
|
glyph = self.bokeh.models.Segment(
|
|
510
546
|
x0="x0", y0="y0", x1="x1", y1="y1", **kw)
|
|
511
547
|
self._fig.add_glyph(source, glyph)
|
|
512
|
-
if isinstance(line_color, dict):
|
|
548
|
+
if isinstance(line_color, dict) and s.colorbar:
|
|
513
549
|
colorbar = self.bokeh.models.ColorBar(
|
|
514
550
|
color_mapper=color_mapper, width=8, title=s.get_label(self._use_latex))
|
|
515
551
|
self._fig.add_layout(colorbar, "right")
|
|
@@ -519,6 +555,10 @@ class BokehBackend(Plot):
|
|
|
519
555
|
x, y, mag, angle, img, colors = s.get_data()
|
|
520
556
|
img = self._get_img(img)
|
|
521
557
|
|
|
558
|
+
self._fig.x_range.flipped = s.at_infinity
|
|
559
|
+
if s.at_infinity:
|
|
560
|
+
mag, angle, img = [np.flip(np.flip(t, axis=0),
|
|
561
|
+
axis=1) for t in [mag, angle, img]]
|
|
522
562
|
source = self.bokeh.models.ColumnDataSource(
|
|
523
563
|
{
|
|
524
564
|
"image": [img],
|
|
@@ -535,7 +575,7 @@ class BokehBackend(Plot):
|
|
|
535
575
|
dh=y.max() - y.min(),
|
|
536
576
|
)
|
|
537
577
|
|
|
538
|
-
if colors is not None:
|
|
578
|
+
if (colors is not None) and s.colorbar:
|
|
539
579
|
# chroma/phase-colorbar
|
|
540
580
|
cm1 = self.bokeh.models.LinearColorMapper(
|
|
541
581
|
palette=[tuple(c) for c in colors],
|
|
@@ -544,7 +584,7 @@ class BokehBackend(Plot):
|
|
|
544
584
|
labels = ["-π", "-π / 2", "0", "π / 2", "π"]
|
|
545
585
|
colorbar1 = self.bokeh.models.ColorBar(
|
|
546
586
|
color_mapper=cm1,
|
|
547
|
-
title="Argument",
|
|
587
|
+
title="Argument" if s.get_label(False) == str(s.expr) else s.get_label(self._use_latex),
|
|
548
588
|
ticker=self.bokeh.models.tickers.FixedTicker(ticks=ticks),
|
|
549
589
|
major_label_overrides={k: v for k, v in zip(ticks, labels)})
|
|
550
590
|
self._fig.add_layout(colorbar1, "right")
|
|
@@ -578,10 +618,21 @@ class BokehBackend(Plot):
|
|
|
578
618
|
)
|
|
579
619
|
|
|
580
620
|
if len(self._fig.legend) > 0:
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
621
|
+
# hide default legend
|
|
622
|
+
self._fig.legend.visible = False
|
|
623
|
+
# add a new legend only showing the appropriate items
|
|
624
|
+
legend_items = []
|
|
625
|
+
for s, r in zip(self.series, self._fig.renderers):
|
|
626
|
+
if (s.show_in_legend and (s.is_2Dline or s.is_geometry) and
|
|
627
|
+
(not s.use_cm)):
|
|
628
|
+
legend_items.append(
|
|
629
|
+
self.bokeh.models.LegendItem(
|
|
630
|
+
label=s.get_label(self._use_latex), renderers=[r]))
|
|
631
|
+
if self.legend and (len(legend_items) > 0):
|
|
632
|
+
legend = self.bokeh.models.Legend(items=legend_items)
|
|
633
|
+
# interactive legend
|
|
634
|
+
legend.click_policy = "hide"
|
|
635
|
+
self._fig.add_layout(legend, "right")
|
|
585
636
|
|
|
586
637
|
def _get_img(self, img):
|
|
587
638
|
np = import_module('numpy')
|
|
@@ -675,13 +726,14 @@ class BokehBackend(Plot):
|
|
|
675
726
|
x, y, z = s.get_data()
|
|
676
727
|
minx, miny, minz = x.min(), y.min(), z.min()
|
|
677
728
|
maxx, maxy, maxz = x.max(), y.max(), z.max()
|
|
678
|
-
cb = self._handles[i]
|
|
679
729
|
rend[i].data_source.data.update({"image": [z]})
|
|
680
730
|
rend[i].glyph.x = minx
|
|
681
731
|
rend[i].glyph.y = miny
|
|
682
732
|
rend[i].glyph.dw = abs(maxx - minx)
|
|
683
733
|
rend[i].glyph.dh = abs(maxy - miny)
|
|
684
|
-
|
|
734
|
+
if s.colorbar:
|
|
735
|
+
cb = self._handles[i]
|
|
736
|
+
cb.color_mapper.update(low=minz, high=maxz)
|
|
685
737
|
|
|
686
738
|
elif s.is_2Dvector:
|
|
687
739
|
x, y, u, v = s.get_data()
|
|
@@ -723,9 +775,10 @@ class BokehBackend(Plot):
|
|
|
723
775
|
},
|
|
724
776
|
)
|
|
725
777
|
rend[i].glyph.line_color = line_color
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
778
|
+
if s.colorbar:
|
|
779
|
+
cb = self._handles[i]
|
|
780
|
+
cb.color_mapper.update(
|
|
781
|
+
low=min(color_val), high=max(color_val))
|
|
729
782
|
|
|
730
783
|
elif s.is_complex and s.is_domain_coloring and not s.is_3Dsurface:
|
|
731
784
|
x, y, mag, angle, img, _ = s.get_data()
|
|
@@ -38,9 +38,10 @@ class K3DBackend(Plot):
|
|
|
38
38
|
- ``scale``: a float number acting as a scale multiplier.
|
|
39
39
|
- ``pivot``: indicates the part of the arrow that is anchored to the
|
|
40
40
|
X, Y, Z grid. It can be ``"tail", "mid", "middle", "tip"``.
|
|
41
|
-
- ``color``: set a solid color by specifying an integer color
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
- ``color``: set a solid color by specifying an integer color, or
|
|
42
|
+
a colormap by specifying one of k3d's colormaps.
|
|
43
|
+
If this key is not provided, a default color or colormap is used,
|
|
44
|
+
depending on the value of ``use_cm``.
|
|
44
45
|
|
|
45
46
|
Set ``use_cm=False`` to switch to a default solid color.
|
|
46
47
|
|
|
@@ -297,13 +298,13 @@ class K3DBackend(Plot):
|
|
|
297
298
|
indices = Triangulation(x, y).triangles.astype(np.uint32)
|
|
298
299
|
attribute = s.eval_color_func(vertices[:, 0], vertices[:, 1], vertices[:, 2])
|
|
299
300
|
|
|
300
|
-
# self._high_aspect_ratio(x, y, z)
|
|
301
301
|
a = dict(
|
|
302
302
|
name=s.get_label(self._use_latex, "%s") if self._show_label else None,
|
|
303
303
|
side="double",
|
|
304
304
|
flat_shading=False,
|
|
305
305
|
wireframe=False,
|
|
306
306
|
color=self._convert_to_int(next(self._cl)) if s.surface_color is None else s.surface_color,
|
|
307
|
+
colorLegend=self.legend or s.use_cm,
|
|
307
308
|
)
|
|
308
309
|
if s.use_cm:
|
|
309
310
|
a["color_map"] = next(self._cm)
|
|
@@ -344,8 +345,8 @@ class K3DBackend(Plot):
|
|
|
344
345
|
|
|
345
346
|
stream_kw = s.rendering_kw.copy()
|
|
346
347
|
skw = dict(width=0.1, shader="mesh")
|
|
347
|
-
if s.use_cm
|
|
348
|
-
skw["color_map"] = next(self._cm)
|
|
348
|
+
if s.use_cm:
|
|
349
|
+
skw["color_map"] = stream_kw.get("color", next(self._cm))
|
|
349
350
|
skw["color_range"] = [float(np.nanmin(color_val)), float(np.nanmax(color_val))]
|
|
350
351
|
skw["attribute"] = color_val
|
|
351
352
|
else:
|
|
@@ -363,8 +364,8 @@ class K3DBackend(Plot):
|
|
|
363
364
|
qkw = dict(scale=1)
|
|
364
365
|
qkw = merge(qkw, s.rendering_kw)
|
|
365
366
|
quiver_kw = s.rendering_kw
|
|
366
|
-
if s.use_cm
|
|
367
|
-
colormap = next(self._cm)
|
|
367
|
+
if s.use_cm:
|
|
368
|
+
colormap = quiver_kw.get("color", next(self._cm))
|
|
368
369
|
# store useful info for interactive vector plots
|
|
369
370
|
self._handles[ii] = [qkw, colormap]
|
|
370
371
|
else:
|
|
@@ -413,18 +414,22 @@ class K3DBackend(Plot):
|
|
|
413
414
|
flat_shading=False,
|
|
414
415
|
wireframe=False,
|
|
415
416
|
color=self._convert_to_int(next(self._cl)),
|
|
416
|
-
|
|
417
|
+
colorLegend=self.legend or s.use_cm,
|
|
417
418
|
)
|
|
418
419
|
if s.use_cm:
|
|
419
420
|
colors = colors.reshape((-1, 3))
|
|
420
421
|
a["colors"] = [self._rgb_to_int(c) for c in colors]
|
|
421
422
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
r
|
|
427
|
-
|
|
423
|
+
if colorscale is None:
|
|
424
|
+
# grayscale colormap
|
|
425
|
+
r = [0, 0, 0, 0, 1, 1, 1, 1]
|
|
426
|
+
else:
|
|
427
|
+
r = []
|
|
428
|
+
loc = np.linspace(0, 1, colorscale.shape[0])
|
|
429
|
+
colorscale = colorscale / 255
|
|
430
|
+
for l, c in zip(loc, colorscale):
|
|
431
|
+
r.append(l)
|
|
432
|
+
r += list(c)
|
|
428
433
|
|
|
429
434
|
a["color_map"] = r
|
|
430
435
|
a["color_range"] = [-np.pi, np.pi]
|