vedo.colors

Colors definitions and printing methods.

   1#!/usr/bin/env python3
   2# -*- coding: utf-8 -*-
   3import os
   4import sys
   5import time
   6
   7import numpy as np
   8
   9try:
  10    import vedo.vtkclasses as vtk
  11except ImportError:
  12    import vtkmodules.all as vtk
  13
  14import vedo
  15
  16__docformat__ = "google"
  17
  18__doc__ = """
  19Colors definitions and printing methods.
  20
  21![](https://vedo.embl.es/images/basic/colorcubes.png)
  22"""
  23
  24__all__ = [
  25    "printc",
  26    "printd",
  27    "get_color",
  28    "get_color_name",
  29    "color_map",
  30    "build_palette",
  31    "build_lut",
  32]
  33
  34
  35try:
  36    import matplotlib.cm as _cm_mpl
  37    _has_matplotlib = True
  38    cmaps = {}
  39except ModuleNotFoundError:
  40    from vedo.cmaps import cmaps
  41    _has_matplotlib = False
  42    # see below, this is dealt with in color_map()
  43
  44#########################################################
  45# handy global shortcuts for terminal printing
  46# Ex.: print(colors.red + "hello" + colors.reset)
  47#########################################################
  48red = "\x1b[1m\x1b[31;1m"
  49green = "\x1b[1m\x1b[32;1m"
  50yellow = "\x1b[1m\x1b[33;1m"
  51blue = "\x1b[1m\x1b[34;1m"
  52reset = "\x1b[0m"
  53
  54
  55#########################################################
  56# basic color schemes
  57#########################################################
  58colors = {
  59    # order kind of matters because of pyplot.plot()
  60    "blue9": "#a8cbfe",  # bootstrap5 colors
  61    "blue8": "#81b4fe",
  62    "blue7": "#5a9cfe",
  63    "blue6": "#3485fd",
  64    "blue5": "#0d6efd",
  65    "blue4": "#0b5cd5",
  66    "blue3": "#094bac",
  67    "blue2": "#073984",
  68    "blue1": "#05285b",
  69    "indigo9": "#c8a9fa",
  70    "indigo8": "#af83f8",
  71    "indigo7": "#975cf6",
  72    "indigo6": "#7e36f4",
  73    "indigo5": "#6610f2",
  74    "indigo4": "#560dcb",
  75    "indigo3": "#450ba5",
  76    "indigo2": "#35087e",
  77    "indigo1": "#250657",
  78    "purple9": "#cbbbe9",
  79    "purple8": "#b49ddf",
  80    "purple7": "#9d7ed5",
  81    "purple6": "#8660cb",
  82    "purple5": "#6f42c1",
  83    "purple4": "#5d37a2",
  84    "purple3": "#4b2d83",
  85    "purple2": "#3a2264",
  86    "purple1": "#281845",
  87    "pink9": "#f0b6d3",
  88    "pink8": "#ea95bf",
  89    "pink7": "#e374ab",
  90    "pink6": "#dd5498",
  91    "pink5": "#d63384",
  92    "pink4": "#b42b6f",
  93    "pink3": "#92235a",
  94    "pink2": "#6f1b45",
  95    "pink1": "#4d1230",
  96    "red9": "#f2b6bc",
  97    "red8": "#ed969e",
  98    "red7": "#e77681",
  99    "red6": "#e25563",
 100    "red5": "#dc3545",
 101    "red4": "#b92d3a",
 102    "red3": "#96242f",
 103    "red2": "#721c24",
 104    "red1": "#4f1319",
 105    "orange9": "#fed1aa",
 106    "orange8": "#febc85",
 107    "orange7": "#fea75f",
 108    "orange6": "#fd933a",
 109    "orange5": "#fd7e14",
 110    "orange4": "#d56a11",
 111    "orange3": "#ac560e",
 112    "orange2": "#84420a",
 113    "orange1": "#5b2d07",
 114    "yellow9": "#ffe9a6",
 115    "yellow8": "#ffdf7e",
 116    "yellow7": "#ffd556",
 117    "yellow6": "#ffcb2f",
 118    "yellow5": "#ffc107",
 119    "yellow4": "#d6a206",
 120    "yellow3": "#ad8305",
 121    "yellow2": "#856404",
 122    "yellow1": "#5c4503",
 123    "green9": "#b2dfbc",
 124    "green8": "#8fd19e",
 125    "green7": "#6dc381",
 126    "green6": "#4ab563",
 127    "green5": "#28a745",
 128    "green4": "#228c3a",
 129    "green3": "#1b722f",
 130    "green2": "#155724",
 131    "green1": "#0e3c19",
 132    "teal9": "#afecda",
 133    "teal8": "#8be3c9",
 134    "teal7": "#67dab8",
 135    "teal6": "#44d2a8",
 136    "teal5": "#20c997",
 137    "teal4": "#1ba97f",
 138    "teal3": "#168967",
 139    "teal2": "#11694f",
 140    "teal1": "#0c4836",
 141    "cyan9": "#abdee5",
 142    "cyan8": "#86cfda",
 143    "cyan7": "#61c0cf",
 144    "cyan6": "#3cb1c3",
 145    "cyan5": "#17a2b8",
 146    "cyan4": "#13889b",
 147    "cyan3": "#106e7d",
 148    "cyan2": "#0c5460",
 149    "cyan1": "#083a42",
 150    "gray9": "#f8f9fa",
 151    "gray8": "#e9edef",
 152    "gray7": "#dee2e6",
 153    "gray6": "#ced4da",
 154    "gray5": "#adb5bd",
 155    "gray4": "#6c757d",
 156    "gray3": "#495057",
 157    "gray2": "#343a40",
 158    "gray1": "#212529",
 159    "aliceblue": "#F0F8FF",  # matplotlib scheme
 160    "antiquewhite": "#FAEBD7",
 161    "aqua": "#00FFFF",
 162    "aquamarine": "#7FFFD4",
 163    "azure": "#F0FFFF",
 164    "beige": "#F5F5DC",
 165    "bisque": "#FFE4C4",
 166    "black": "#000000",
 167    "blanchedalmond": "#FFEBCD",
 168    "blue": "#0f00fb",  # "0000FF",
 169    "blueviolet": "#8A2BE2",
 170    "brown": "#A52A2A",
 171    "burlywood": "#DEB887",
 172    "cadetblue": "#5F9EA0",
 173    "chartreuse": "#7FFF00",
 174    "chocolate": "#D2691E",
 175    "coral": "#FF7F50",
 176    "cornflowerblue": "#6495ED",
 177    "cornsilk": "#FFF8DC",
 178    "crimson": "#DC143C",
 179    "cyan": "#00FFFF",
 180    "darkblue": "#00008B",
 181    "darkcyan": "#008B8B",
 182    "darkgoldenrod": "#B8860B",
 183    "darkgray": "#A9A9A9",
 184    "darkgreen": "#006400",
 185    "darkkhaki": "#BDB76B",
 186    "darkmagenta": "#8B008B",
 187    "darkolivegreen": "#556B2F",
 188    "darkorange": "#FF8C00",
 189    "darkorchid": "#9932CC",
 190    "darkred": "#8B0000",
 191    "darksalmon": "#E9967A",
 192    "darkseagreen": "#8FBC8F",
 193    "darkslateblue": "#483D8B",
 194    "darkslategray": "#2F4F4F",
 195    "darkturquoise": "#00CED1",
 196    "darkviolet": "#9400D3",
 197    "deeppink": "#FF1493",
 198    "deepskyblue": "#00BFFF",
 199    "dimgray": "#696969",
 200    "dodgerblue": "#1E90FF",
 201    "firebrick": "#B22222",
 202    "floralwhite": "#FFFAF0",
 203    "forestgreen": "#228B22",
 204    "fuchsia": "#FF00FF",
 205    "gainsboro": "#DCDCDC",
 206    "ghostwhite": "#F8F8FF",
 207    "gold": "#FFD700",
 208    "goldenrod": "#DAA520",
 209    "gray": "#808080",
 210    "green": "#047f10",  # "#008000",
 211    "greenyellow": "#ADFF2F",
 212    "honeydew": "#F0FFF0",
 213    "hotpink": "#FF69B4",
 214    "indianred": "#CD5C5C",
 215    "indigo": "#4B0082",
 216    "ivory": "#FFFFF0",
 217    "khaki": "#F0E68C",
 218    "lavender": "#E6E6FA",
 219    "lavenderblush": "#FFF0F5",
 220    "lawngreen": "#7CFC00",
 221    "lemonchiffon": "#FFFACD",
 222    "lightblue": "#ADD8E6",
 223    "lightcoral": "#F08080",
 224    "lightcyan": "#E0FFFF",
 225    "lightgray": "#D3D3D3",
 226    "lightgreen": "#90EE90",
 227    "lightpink": "#FFB6C1",
 228    "lightsalmon": "#FFA07A",
 229    "lightseagreen": "#20B2AA",
 230    "lightskyblue": "#87CEFA",
 231    "lightsteelblue": "#B0C4DE",
 232    "lightyellow": "#FFFFE0",
 233    "lime": "#00FF00",
 234    "limegreen": "#32CD32",
 235    "linen": "#FAF0E6",
 236    "magenta": "#FF00FF",
 237    "maroon": "#800000",
 238    "mediumaquamarine": "#66CDAA",
 239    "mediumblue": "#0000CD",
 240    "mediumorchid": "#BA55D3",
 241    "mediumpurple": "#9370DB",
 242    "mediumseagreen": "#3CB371",
 243    "mediumslateblue": "#7B68EE",
 244    "mediumspringgreen": "#00FA9A",
 245    "mediumturquoise": "#48D1CC",
 246    "mediumvioletred": "#C71585",
 247    "midnightblue": "#191970",
 248    "mintcream": "#F5FFFA",
 249    "mistyrose": "#FFE4E1",
 250    "moccasin": "#FFE4B5",
 251    "navajowhite": "#FFDEAD",
 252    "navy": "#000080",
 253    "oldlace": "#FDF5E6",
 254    "olive": "#808000",
 255    "olivedrab": "#6B8E23",
 256    "orange": "#FFA500",
 257    "orangered": "#FF4500",
 258    "orchid": "#DA70D6",
 259    "palegoldenrod": "#EEE8AA",
 260    "palegreen": "#98FB98",
 261    "paleturquoise": "#AFEEEE",
 262    "palevioletred": "#DB7093",
 263    "papayawhip": "#FFEFD5",
 264    "peachpuff": "#FFDAB9",
 265    "peru": "#CD853F",
 266    "pink": "#FFC0CB",
 267    "plum": "#DDA0DD",
 268    "powderblue": "#B0E0E6",
 269    "purple": "#800080",
 270    "rebeccapurple": "#663399",
 271    "red": "#fe1e1f",  # "#FF0000",
 272    "rosybrown": "#BC8F8F",
 273    "royalblue": "#4169E1",
 274    "saddlebrown": "#8B4513",
 275    "salmon": "#FA8072",
 276    "sandybrown": "#F4A460",
 277    "seagreen": "#2E8B57",
 278    "seashell": "#FFF5EE",
 279    "sienna": "#A0522D",
 280    "silver": "#C0C0C0",
 281    "skyblue": "#87CEEB",
 282    "slateblue": "#6A5ACD",
 283    "slategray": "#708090",
 284    "snow": "#FFFAFA",
 285    "blackboard": "#393939",
 286    "springgreen": "#00FF7F",
 287    "steelblue": "#4682B4",
 288    "tan": "#D2B48C",
 289    "teal": "#008080",
 290    "thistle": "#D8BFD8",
 291    "tomato": "#FF6347",
 292    "turquoise": "#40E0D0",
 293    "violet": "#EE82EE",
 294    "wheat": "#F5DEB3",
 295    "white": "#FFFFFF",
 296    "whitesmoke": "#F5F5F5",
 297    "yellow": "#ffff36",  # "#FFFF00",
 298    "yellowgreen": "#9ACD32",
 299}
 300
 301
 302color_nicks = {  # color nicknames
 303    "bb": "blackboard",
 304    "lb": "lightblue",  # light
 305    "lg": "lightgreen",
 306    "lr": "orangered",
 307    "lc": "lightcyan",
 308    "ls": "lightsalmon",
 309    "ly": "lightyellow",
 310    "dr": "darkred",  # dark
 311    "db": "darkblue",
 312    "dg": "darkgreen",
 313    "dm": "darkmagenta",
 314    "dc": "darkcyan",
 315    "ds": "darksalmon",
 316    "dv": "darkviolet",
 317    "b1": "blue1",  # bootstrap5 colors
 318    "b2": "blue2",
 319    "b3": "blue3",
 320    "b4": "blue4",
 321    "b5": "blue5",
 322    "b6": "blue6",
 323    "b7": "blue7",
 324    "b8": "blue8",
 325    "b9": "blue9",
 326    "i1": "indigo1",
 327    "i2": "indigo2",
 328    "i3": "indigo3",
 329    "i4": "indigo4",
 330    "i5": "indigo5",
 331    "i6": "indigo6",
 332    "i7": "indigo7",
 333    "i8": "indigo8",
 334    "i9": "indigo9",
 335    "p1": "purple1",
 336    "p2": "purple2",
 337    "p3": "purple3",
 338    "p4": "purple4",
 339    "p5": "purple5",
 340    "p6": "purple6",
 341    "p7": "purple7",
 342    "p8": "purple8",
 343    "p9": "purple9",
 344    "r1": "red1",
 345    "r2": "red2",
 346    "r3": "red3",
 347    "r4": "red4",
 348    "r5": "red5",
 349    "r6": "red6",
 350    "r7": "red7",
 351    "r8": "red8",
 352    "r9": "red9",
 353    "o1": "orange1",
 354    "o2": "orange2",
 355    "o3": "orange3",
 356    "o4": "orange4",
 357    "o5": "orange5",
 358    "o6": "orange6",
 359    "o7": "orange7",
 360    "o8": "orange8",
 361    "o9": "orange9",
 362    "y1": "yellow1",
 363    "y2": "yellow2",
 364    "y3": "yellow3",
 365    "y4": "yellow4",
 366    "y5": "yellow5",
 367    "y6": "yellow6",
 368    "y7": "yellow7",
 369    "y8": "yellow8",
 370    "y9": "yellow9",
 371    "g1": "green1",
 372    "g2": "green2",
 373    "g3": "green3",
 374    "g4": "green4",
 375    "g5": "green5",
 376    "g6": "green6",
 377    "g7": "green7",
 378    "g8": "green8",
 379    "g9": "green9",
 380    "k1": "gray1",
 381    "k2": "gray2",
 382    "k3": "gray3",
 383    "k4": "gray4",
 384    "k5": "gray5",
 385    "k6": "gray6",
 386    "k7": "gray7",
 387    "k8": "gray8",
 388    "k9": "gray9",
 389    "a": "aqua",
 390    "b": "blue",
 391    "c": "cyan",
 392    "d": "gold",
 393    "f": "fuchsia",
 394    "g": "green",
 395    "i": "indigo",
 396    "k": "black",
 397    "m": "magenta",
 398    "n": "navy",
 399    "l": "lavender",
 400    "o": "orange",
 401    "p": "purple",
 402    "r": "red",
 403    "s": "salmon",
 404    "t": "tomato",
 405    "v": "violet",
 406    "y": "yellow",
 407    "w": "white",
 408}
 409
 410
 411# available colormap names:
 412cmaps_names = (
 413    "Accent",
 414    "Accent_r",
 415    "Blues",
 416    "Blues_r",
 417    "BrBG",
 418    "BrBG_r",
 419    "BuGn",
 420    "BuGn_r",
 421    "BuPu",
 422    "BuPu_r",
 423    "CMRmap",
 424    "CMRmap_r",
 425    "Dark2",
 426    "Dark2_r",
 427    "GnBu",
 428    "GnBu_r",
 429    "Greens",
 430    "Greens_r",
 431    "Greys",
 432    "Greys_r",
 433    "OrRd",
 434    "OrRd_r",
 435    "Oranges",
 436    "Oranges_r",
 437    "PRGn",
 438    "PRGn_r",
 439    "Paired",
 440    "Paired_r",
 441    "Pastel1",
 442    "Pastel1_r",
 443    "Pastel2",
 444    "Pastel2_r",
 445    "PiYG",
 446    "PiYG_r",
 447    "PuBu",
 448    "PuBuGn",
 449    "PuBuGn_r",
 450    "PuBu_r",
 451    "PuOr",
 452    "PuOr_r",
 453    "PuRd",
 454    "PuRd_r",
 455    "Purples",
 456    "Purples_r",
 457    "RdBu",
 458    "RdBu_r",
 459    "RdGy",
 460    "RdGy_r",
 461    "RdPu",
 462    "RdPu_r",
 463    "RdYlBu",
 464    "RdYlBu_r",
 465    "RdYlGn",
 466    "RdYlGn_r",
 467    "Reds",
 468    "Reds_r",
 469    "Set1",
 470    "Set1_r",
 471    "Set2",
 472    "Set2_r",
 473    "Set3",
 474    "Set3_r",
 475    "Spectral",
 476    "Spectral_r",
 477    "Wistia",
 478    "Wistia_r",
 479    "YlGn",
 480    "YlGnBu",
 481    "YlGnBu_r",
 482    "YlGn_r",
 483    "YlOrBr",
 484    "YlOrBr_r",
 485    "YlOrRd",
 486    "YlOrRd_r",
 487    "afmhot",
 488    "afmhot_r",
 489    "autumn",
 490    "autumn_r",
 491    "binary",
 492    "binary_r",
 493    "bone",
 494    "bone_r",
 495    "brg",
 496    "brg_r",
 497    "bwr",
 498    "bwr_r",
 499    "cividis",
 500    "cividis_r",
 501    "cool",
 502    "cool_r",
 503    "coolwarm",
 504    "coolwarm_r",
 505    "copper",
 506    "copper_r",
 507    "cubehelix",
 508    "cubehelix_r",
 509    "flag",
 510    "flag_r",
 511    "gist_earth",
 512    "gist_earth_r",
 513    "gist_gray",
 514    "gist_gray_r",
 515    "gist_heat",
 516    "gist_heat_r",
 517    "gist_ncar",
 518    "gist_ncar_r",
 519    "gist_rainbow",
 520    "gist_rainbow_r",
 521    "gist_stern",
 522    "gist_stern_r",
 523    "gist_yarg",
 524    "gist_yarg_r",
 525    "gnuplot",
 526    "gnuplot2",
 527    "gnuplot2_r",
 528    "gnuplot_r",
 529    "gray_r",
 530    "hot",
 531    "hot_r",
 532    "hsv",
 533    "hsv_r",
 534    "inferno",
 535    "inferno_r",
 536    "jet",
 537    "jet_r",
 538    "magma",
 539    "magma_r",
 540    "nipy_spectral",
 541    "nipy_spectral_r",
 542    "ocean",
 543    "ocean_r",
 544    "pink_r",
 545    "plasma",
 546    "plasma_r",
 547    "prism",
 548    "prism_r",
 549    "rainbow",
 550    "rainbow_r",
 551    "seismic",
 552    "seismic_r",
 553    "spring",
 554    "spring_r",
 555    "summer",
 556    "summer_r",
 557    "tab10",
 558    "tab10_r",
 559    "tab20",
 560    "tab20_r",
 561    "tab20b",
 562    "tab20b_r",
 563    "tab20c",
 564    "tab20c_r",
 565    "terrain",
 566    "terrain_r",
 567    "twilight",
 568    "twilight_r",
 569    "twilight_shifted",
 570    "twilight_shifted_r",
 571    "viridis",
 572    "viridis_r",
 573    "winter",
 574    "winter_r",
 575)
 576
 577
 578# default color palettes when using an index
 579palettes = (
 580    (
 581        (1.0, 0.832, 0.000),  # gold
 582        (0.960, 0.509, 0.188),
 583        (0.901, 0.098, 0.194),
 584        (0.235, 0.85, 0.294),
 585        (0.46, 0.48, 0.000),
 586        (0.274, 0.941, 0.941),
 587        (0.0, 0.509, 0.784),
 588        (0.1, 0.1, 0.900),
 589        (0.902, 0.7, 1.000),
 590        (0.941, 0.196, 0.901),
 591    ),
 592    (
 593        (1.0, 0.832, 0),    # gold
 594        (0.59, 0.0, 0.09),  # dark red
 595        (0.5, 0.5, 0),      # yellow-green
 596        (0.0, 0.66, 0.42),  # green blue
 597        (0.5, 1.0, 0.0),    # green
 598        (0.0, 0.18, 0.65),  # blue
 599        (0.4, 0.0, 0.4),    # plum
 600        (0.4, 0.0, 0.6),
 601        (0.2, 0.4, 0.6),
 602        (0.1, 0.3, 0.2),
 603    ),
 604    (
 605        (0.010, 0.0706, 0.098),  #  -> black
 606        (0.0196, 0.369, 0.447),
 607        (0.0745, 0.573, 0.584),
 608        (0.584, 0.820, 0.741),
 609        (0.914, 0.847, 0.663),
 610        (0.929, 0.616, 0.149),
 611        (0.788, 0.412, 0.110),
 612        (0.729, 0.259, 0.0902),
 613        (0.678, 0.153, 0.110),
 614        (0.604, 0.153, 0.165),  #  -> red3
 615    ),
 616    (
 617        (0.345, 0.188, 0.071),  #  -> orange1
 618        (0.498, 0.314, 0.161),
 619        (0.573, 0.404, 0.239),
 620        (0.651, 0.545, 0.400),
 621        (0.714, 0.678, 0.569),
 622        (0.761, 0.773, 0.671),
 623        (0.643, 0.675, 0.533),
 624        (0.396, 0.427, 0.298),
 625        (0.255, 0.282, 0.204),
 626        (0.200, 0.239, 0.165),  #  -> blackboard
 627    ),
 628    (
 629        (0.937, 0.969, 0.820),  #  -> beige
 630        (0.729, 0.851, 0.714),
 631        (0.671, 0.639, 0.396),
 632        (0.447, 0.180, 0.180),
 633        (0.259, 0.055, 0.082),  #  -> red1
 634        (0.937, 0.969, 0.820),  #  -> beige
 635        (0.729, 0.851, 0.714),
 636        (0.671, 0.639, 0.396),
 637        (0.447, 0.180, 0.180),
 638        (0.259, 0.055, 0.082),  #  -> red1
 639    ),
 640    (
 641        (0.933, 0.298, 0.443),  #  -> red6
 642        (0.996, 0.824, 0.431),
 643        (0.082, 0.835, 0.631),
 644        (0.094, 0.537, 0.690),
 645        (0.035, 0.231, 0.294),  #  -> cyan1
 646        (0.933, 0.298, 0.443),  #  -> red6
 647        (0.996, 0.824, 0.431),
 648        (0.082, 0.835, 0.631),
 649        (0.094, 0.537, 0.690),
 650        (0.035, 0.231, 0.294),  #  -> cyan1
 651    ),
 652)
 653
 654
 655emoji = {
 656    ":bomb:": "\U0001F4A5",
 657    ":sparks:": "\U00002728",
 658    ":thumbup:": "\U0001F44D",
 659    ":target:": "\U0001F3AF",
 660    ":save:": "\U0001F4BE",
 661    ":noentry:": "\U000026D4",
 662    ":video:": "\U0001F4FD",
 663    ":lightning:": "\U000026A1",
 664    ":camera:": "\U0001F4F8",
 665    ":times:": "\U0000274C",
 666    ":world:": "\U0001F30D",
 667    ":rainbow:": "\U0001F308",
 668    ":idea:": "\U0001F4A1",
 669    ":pin:": "\U0001F4CC",
 670    ":construction:": "\U0001F6A7",
 671    ":rocket:": "\U0001F680",
 672    ":hourglass:": "\U000023F3",
 673    ":prohibited:": "\U0001F6AB",
 674    ":checked:": "\U00002705",
 675    ":smile:": "\U0001F642",
 676    ":sad:": "\U0001F612",
 677    ":star:": "\U00002B50",
 678    ":zzz:": "\U0001F4A4",
 679    ":mu:": "\U000003BC",
 680    ":pi:": "\U000003C0",
 681    ":sigma:": "\U000003C3",
 682    ":rightarrow:": "\U000027A1",
 683}
 684
 685
 686# terminal or notebook can do color print
 687def _has_colors(stream):
 688    try:
 689        import IPython
 690        return True
 691    except:
 692        pass
 693
 694    if not hasattr(stream, "isatty"):
 695        return False
 696    if not stream.isatty():
 697        return False
 698    return True
 699_terminal_has_colors = _has_colors(sys.stdout)
 700
 701
 702def _is_sequence(arg):
 703    # Check if input is iterable.
 704    if hasattr(arg, "strip"):
 705        return False
 706    if hasattr(arg, "__getslice__"):
 707        return True
 708    if hasattr(arg, "__iter__"):
 709        return True
 710    return False
 711
 712
 713def get_color(rgb=None, hsv=None):
 714    """
 715    Convert a color or list of colors to (r,g,b) format from many different input formats.
 716
 717    Set `hsv` to input as (hue, saturation, value).
 718
 719    Example:
 720         - `RGB    = (255, 255, 255)` corresponds to white
 721         - `rgb    = (1,1,1)` is again white
 722         - `hex    = #FFFF00` is yellow
 723         - `string = 'white'`
 724         - `string = 'w'` is white nickname
 725         - `string = 'dr'` is darkred
 726         - `string = 'red4'` is a shade of red
 727         - `int    =  7` picks color nr. 7 in a predefined color list
 728         - `int    = -7` picks color nr. 7 in a different predefined list
 729
 730
 731    Examples:
 732        - [colorcubes.py](https://github.com/marcomusy/vedo/tree/master/examples/basic/colorcubes.py)
 733
 734            ![](https://vedo.embl.es/images/basic/colorcubes.png)
 735    """
 736    # recursion, return a list if input is list of colors:
 737    if _is_sequence(rgb) and (len(rgb) > 3 or _is_sequence(rgb[0])):
 738        seqcol = []
 739        for sc in rgb:
 740            seqcol.append(get_color(sc))
 741        return seqcol
 742
 743    # because they are most common:
 744    if isinstance(rgb, str):
 745        if rgb == "r":
 746            return (0.9960784313725, 0.11764705882352, 0.121568627450980)
 747        elif rgb == "g":
 748            return (0.0156862745098, 0.49803921568627, 0.062745098039215)
 749        elif rgb == "b":
 750            return (0.0588235294117, 0.0, 0.984313725490196)
 751
 752    if str(rgb).isdigit():
 753        rgb = int(rgb)
 754
 755    if hsv:
 756        c = hsv2rgb(hsv)
 757    else:
 758        c = rgb
 759
 760    if _is_sequence(c):
 761        if c[0] <= 1 and c[1] <= 1 and c[2] <= 1:
 762            return c  # already rgb
 763        if len(c) == 3:
 764            return list(np.array(c) / 255.0)  # RGB
 765        return (c[0] / 255.0, c[1] / 255.0, c[2] / 255.0, c[3])  # RGBA
 766
 767    elif isinstance(c, str):  # is string
 768        c = c.replace("grey", "gray").replace(" ", "")
 769        if 0 < len(c) < 3:  # single/double letter color
 770            if c.lower() in color_nicks:
 771                c = color_nicks[c.lower()]
 772            else:
 773                vedo.logger.warning(
 774                    f"Unknown color nickname {c}\nAvailable abbreviations: {color_nicks}"
 775                )
 776                return (0.5, 0.5, 0.5)
 777
 778        if c.lower() in colors:  # matplotlib name color
 779            c = colors[c.lower()]
 780            # from now format is hex!
 781
 782        if c.startswith("#"):  # hex to rgb
 783            h = c.lstrip("#")
 784            rgb255 = list(int(h[i : i + 2], 16) for i in (0, 2, 4))
 785            rgbh = np.array(rgb255) / 255.0
 786            if np.sum(rgbh) > 3:
 787                vedo.logger.error(f"in get_color(): Wrong hex color {c}")
 788                return (0.5, 0.5, 0.5)
 789            return tuple(rgbh)
 790
 791        else:  # vtk name color
 792            namedColors = vtk.vtkNamedColors()
 793            rgba = [0, 0, 0, 0]
 794            namedColors.GetColor(c, rgba)
 795            return (rgba[0] / 255.0, rgba[1] / 255.0, rgba[2] / 255.0)
 796
 797    elif isinstance(c, (int, float)):  # color number
 798        return palettes[vedo.settings.palette % len(palettes)][abs(int(c)) % 10]
 799
 800    return (0.5, 0.5, 0.5)
 801
 802
 803def get_color_name(c):
 804    """Find the name of the closest color."""
 805    c = np.array(get_color(c))  # reformat to rgb
 806    mdist = 99.0
 807    kclosest = ""
 808    for key in colors:
 809        ci = np.array(get_color(key))
 810        d = np.linalg.norm(c - ci)
 811        if d < mdist:
 812            mdist = d
 813            kclosest = str(key)
 814    return kclosest
 815
 816
 817def hsv2rgb(hsv):
 818    """Convert HSV to RGB color."""
 819    ma = vtk.vtkMath()
 820    rgb = [0, 0, 0]
 821    ma.HSVToRGB(hsv, rgb)
 822    return rgb
 823
 824
 825def rgb2hsv(rgb):
 826    """Convert RGB to HSV color."""
 827    ma = vtk.vtkMath()
 828    hsv = [0, 0, 0]
 829    ma.RGBToHSV(get_color(rgb), hsv)
 830    return hsv
 831
 832
 833def rgb2hex(rgb):
 834    """Convert RGB to Hex color."""
 835    h = "#%02x%02x%02x" % (int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255))
 836    return h
 837
 838
 839def hex2rgb(hx):
 840    """Convert Hex to rgb color."""
 841    h = hx.lstrip("#")
 842    rgb255 = [int(h[i : i + 2], 16) for i in (0, 2, 4)]
 843    return (rgb255[0] / 255.0, rgb255[1] / 255.0, rgb255[2] / 255.0)
 844
 845
 846def color_map(value, name="jet", vmin=None, vmax=None):
 847    """
 848    Map a real value in range [vmin, vmax] to a (r,g,b) color scale.
 849
 850    Return the (r,g,b) color, or a list of (r,g,b) colors.
 851
 852    Arguments:
 853        value : *(float, list)*
 854            scalar value to transform into a color
 855        name : *(str, matplotlib.colors.LinearSegmentedColormap)*
 856            color map name
 857
 858    Very frequently used color maps are:
 859
 860        ![](https://user-images.githubusercontent.com/32848391/50738804-577e1680-11d8-11e9-929e-fca17a8ac6f3.jpg)
 861
 862    A more complete color maps list:
 863
 864        ![](https://matplotlib.org/1.2.1/_images/show_colormaps.png)
 865
 866    .. note:: Can also directly use and customize a matplotlib color map
 867
 868    Example:
 869        ```python
 870        from vedo import color_map
 871        import matplotlib.cm as cm
 872        print( color_map(0.2, cm.flag, 0, 1) )
 873        # (1.0, 0.809016994374948, 0.6173258487801733)
 874        ```
 875
 876    Examples:
 877        - [plot_bars.py](https://github.com/marcomusy/vedo/tree/master/examples/pyplot/plot_bars.py)
 878
 879            <img src="https://vedo.embl.es/images/pyplot/plot_bars.png" width="400"/>
 880
 881    """
 882    cut = _is_sequence(value)  # to speed up later
 883
 884    if cut:
 885        values = np.asarray(value)
 886        if vmin is None:
 887            vmin = np.min(values)
 888        if vmax is None:
 889            vmax = np.max(values)
 890        values = np.clip(values, vmin, vmax)
 891        values = (values - vmin) / (vmax - vmin)
 892    else:
 893        if vmin is None:
 894            vedo.logger.warning("in color_map() you must specify vmin! Assume 0.")
 895            vmin = 0
 896        if vmax is None:
 897            vedo.logger.warning("in color_map() you must specify vmax! Assume 1.")
 898            vmax = 1
 899        values = [(value - vmin) / (vmax - vmin)]
 900
 901    if _has_matplotlib:
 902        # matplotlib is available, use it! ###########################
 903        if isinstance(name, str):
 904            mp = _cm_mpl.get_cmap(name=name)
 905        else:
 906            mp = name  # assume matplotlib.colors.LinearSegmentedColormap
 907        result = mp(values)[:, [0, 1, 2]]
 908
 909    else:
 910        # matplotlib not available ###################################
 911        invert = False
 912        if name.endswith("_r"):
 913            invert = True
 914            name = name.replace("_r", "")
 915        try:
 916            cmap = cmaps[name]
 917        except KeyError:
 918            vedo.logger.error(f"in color_map(), no color map with name {name} or {name}_r")
 919            vedo.logger.error(f"Available color maps are:\n{cmaps.keys()}")
 920            return np.array([0.5, 0.5, 0.5])
 921
 922        result = []
 923        n = len(cmap) - 1
 924        for v in values:
 925            iv = int(v * n)
 926            if invert:
 927                iv = n - iv
 928            rgb = hex2rgb(cmap[iv])
 929            result.append(rgb)
 930        result = np.array(result)
 931
 932    if cut:
 933        return result
 934    return result[0]
 935
 936
 937def build_palette(color1, color2, n, hsv=True):
 938    """
 939    Generate N colors starting from `color1` to `color2`
 940    by linear interpolation in HSV or RGB spaces.
 941
 942    Arguments:
 943        N : (int)
 944            number of output colors.
 945        color1 : (color)
 946            first color.
 947        color2 : (color)
 948            second color.
 949        hsv : (bool)
 950            if `False`, interpolation is calculated in RGB space.
 951
 952    Examples:
 953        - [mesh_custom.py](https://github.com/marcomusy/vedo/tree/master/examples/basic/mesh_custom.py)
 954
 955            ![](https://vedo.embl.es/images/basic/mesh_custom.png)
 956    """
 957    if hsv:
 958        color1 = rgb2hsv(color1)
 959        color2 = rgb2hsv(color2)
 960    c1 = np.array(get_color(color1))
 961    c2 = np.array(get_color(color2))
 962    cols = []
 963    for f in np.linspace(0, 1, n, endpoint=True):
 964        c = c1 * (1 - f) + c2 * f
 965        if hsv:
 966            c = np.array(hsv2rgb(c))
 967        cols.append(c)
 968    return np.array(cols)
 969
 970
 971def build_lut(
 972    colorlist,
 973    vmin=None,
 974    vmax=None,
 975    below_color=None,
 976    above_color=None,
 977    nan_color=None,
 978    below_alpha=1,
 979    above_alpha=1,
 980    nan_alpha=1,
 981    interpolate=False,
 982):
 983    """
 984    Generate colors in a lookup table (LUT).
 985
 986    Return the `vtkLookupTable` object. This can be fed into `cmap()` method.
 987
 988    Arguments:
 989        colorlist : (list)
 990            a list in the form `[(scalar1, [r,g,b]), (scalar2, 'blue'), ...]`.
 991        vmin : (float)
 992            specify minimum value of scalar range
 993        vmax : (float)
 994            specify maximum value of scalar range
 995        below_color : (color)
 996            color for scalars below the minimum in range
 997        below_alpha : (float)
 998            opacity for scalars below the minimum in range
 999        above_color : (color)
1000            color for scalars above the maximum in range
1001        above_alpha : (float)
1002            alpha for scalars above the maximum in range
1003        nan_color : (color)
1004            color for invalid (nan) scalars
1005        nan_alpha : (float)
1006            alpha for invalid (nan) scalars
1007        interpolate : (bool)
1008            interpolate or not intermediate scalars
1009
1010    Examples:
1011        - [mesh_lut.py](https://github.com/marcomusy/vedo/tree/master/examples/basic/mesh_lut.py)
1012
1013            ![](https://vedo.embl.es/images/basic/mesh_lut.png)
1014    """
1015    ctf = vtk.vtkColorTransferFunction()
1016    ctf.SetColorSpaceToRGB()
1017    ctf.SetScaleToLinear()
1018    alpha_x, alpha_vals = [], []
1019    for sc in colorlist:
1020        if len(sc) >= 3:
1021            scalar, col, alf = sc[:3]
1022        else:
1023            alf = 1
1024            scalar, col = sc
1025        r, g, b = get_color(col)
1026        ctf.AddRGBPoint(scalar, r, g, b)
1027        alpha_x.append(scalar)
1028        alpha_vals.append(alf)
1029
1030    lut = vtk.vtkLookupTable()
1031    lut.SetNumberOfTableValues(256)
1032
1033    x0, x1 = ctf.GetRange()  # range of the introduced values
1034    if vmin is not None:
1035        x0 = vmin
1036    if vmax is not None:
1037        x1 = vmax
1038    ctf.SetRange(x0, x1)
1039    lut.SetRange(x0, x1)
1040
1041    if below_color is not None:
1042        lut.SetBelowRangeColor(list(get_color(below_color)) + [below_alpha])
1043        lut.SetUseBelowRangeColor(True)
1044    if above_color is not None:
1045        lut.SetAboveRangeColor(list(get_color(above_color)) + [above_alpha])
1046        lut.SetUseAboveRangeColor(True)
1047    if nan_color is not None:
1048        lut.SetNanColor(list(get_color(nan_color)) + [nan_alpha])
1049
1050    rgba = (1, 1, 1, 1)
1051    for i in range(256):
1052        p = i / 255
1053        x = (1 - p) * x0 + p * x1
1054        if interpolate:
1055            alf = np.interp(x, alpha_x, alpha_vals)
1056            rgba = list(ctf.GetColor(x)) + [alf]
1057        else:
1058            for c in colorlist:
1059                if x <= c[0]:
1060                    if len(c) == 3:
1061                        alf = c[2]
1062                    else:
1063                        alf = 1
1064                    rgba = list(get_color(c[1])) + [alf]
1065                    break
1066        lut.SetTableValue(i, rgba)
1067
1068    lut.Build()
1069    return lut
1070
1071
1072#########################################################################
1073def printc(
1074    *strings,
1075    c=None,
1076    bc=None,
1077    bold=True,
1078    italic=False,
1079    blink=False,
1080    underline=False,
1081    strike=False,
1082    dim=False,
1083    invert=False,
1084    box="",
1085    end="\n",
1086    flush=True,
1087):
1088    """
1089    Print to terminal in color (any color!).
1090
1091    Arguments:
1092        c : (color)
1093            foreground color name or (r,g,b)
1094        bc : (color)
1095            background color name or (r,g,b)
1096        bold : (bool)
1097            boldface [True]
1098        italic : (bool)
1099            italic [False]
1100        blink : (bool)
1101            blinking text [False]
1102        underline : (bool)
1103            underline text [False]
1104        strike : (bool)
1105            strike through text [False]
1106        dim : (bool)
1107            make text look dimmer [False]
1108        invert : (bool)
1109            invert background and forward colors [False]
1110        box : (bool)
1111            print a box with specified text character ['']
1112        flush : (bool)
1113            flush buffer after printing [True]
1114        end : (str)
1115            the end character to be printed [newline]
1116
1117    Example:
1118        ```python
1119        from vedo.colors import printc
1120        printc('anything', c='tomato', bold=False, end=' ')
1121        printc('anything', 455.5, c='lightblue')
1122        printc(299792.48, c=4)
1123        ```
1124
1125    Examples:
1126        - [printc.py](https://github.com/marcomusy/vedo/tree/master/examples/other/printc.py)
1127
1128        ![](https://user-images.githubusercontent.com/32848391/50739010-2bfc2b80-11da-11e9-94de-011e50a86e61.jpg)
1129    """
1130
1131    if not vedo.settings.enable_print_color or not _terminal_has_colors:
1132        print(*strings, end=end, flush=flush)
1133        return
1134
1135    try:  # -------------------------------------------------------------
1136
1137        txt = str()
1138        ns = len(strings) - 1
1139        separator = " "
1140        offset = 0
1141        for i, s in enumerate(strings):
1142            if i == ns:
1143                separator = ""
1144            if ":" in repr(s):
1145                for k in emoji:
1146                    if k in str(s):
1147                        s = s.replace(k, emoji[k])
1148                        offset += 1
1149                for k, rp in vedo.shapes._reps:  # check symbols in shapes._reps
1150                    if k in str(s):
1151                        s = s.replace(k, rp)
1152                        offset += 1
1153
1154            txt += str(s) + separator
1155
1156        special, cseq = "", ""
1157        oneletter_colors = {
1158            "k": "\u001b[30m",  # because these are supported by most terminals
1159            "r": "\u001b[31m",
1160            "g": "\u001b[32m",
1161            "y": "\u001b[33m",
1162            "b": "\u001b[34m",
1163            "m": "\u001b[35m",
1164            "c": "\u001b[36m",
1165            "w": "\u001b[37m",
1166        }
1167
1168        if c is not None:
1169            if c is True:
1170                c = "g"
1171            elif c is False:
1172                c = "r"
1173
1174            if isinstance(c, str) and c in oneletter_colors:
1175                cseq += oneletter_colors[c]
1176            else:
1177                r, g, b = get_color(c)  # not all terms support this syntax
1178                cseq += f"\x1b[38;2;{int(r*255)};{int(g*255)};{int(b*255)}m"
1179
1180        if bc:
1181            if bc in oneletter_colors:
1182                cseq += oneletter_colors[bc]
1183            else:
1184                r, g, b = get_color(bc)
1185                cseq += f"\x1b[48;2;{int(r*255)};{int(g*255)};{int(b*255)}m"
1186
1187        if box is True:
1188            box = "-"
1189        if underline and not box:
1190            special += "\x1b[4m"
1191        if strike and not box:
1192            special += "\x1b[9m"
1193        if dim:
1194            special += "\x1b[2m"
1195        if invert:
1196            special += "\x1b[7m"
1197        if bold:
1198            special += "\x1b[1m"
1199        if italic:
1200            special += "\x1b[3m"
1201        if blink:
1202            special += "\x1b[5m"
1203
1204        if box and "\n" not in txt:
1205            box = box[0]
1206            boxv = box
1207            if box in ["_", "=", "-", "+", "~"]:
1208                boxv = "|"
1209
1210            if box in ("_", "."):
1211                outtxt = special + cseq + " " + box * (len(txt) + offset + 2) + " \n"
1212                outtxt += boxv + " " * (len(txt) + 2) + boxv + "\n"
1213            else:
1214                outtxt = special + cseq + box * (len(txt) + offset + 4) + "\n"
1215
1216            outtxt += boxv + " " + txt + " " + boxv + "\n"
1217
1218            if box == "_":
1219                outtxt += "|" + box * (len(txt) + offset + 2) + "|" + reset + end
1220            else:
1221                outtxt += box * (len(txt) + offset + 4) + reset + end
1222
1223            sys.stdout.write(outtxt)
1224
1225        else:
1226
1227            out = special + cseq + txt + reset
1228            sys.stdout.write(out + end)
1229
1230    except:  # ------------------------------------------------------------- fallback
1231
1232        try:
1233            print(*strings, end=end)
1234        except UnicodeEncodeError as e:
1235            print(e, end=end)
1236            pass
1237
1238    if flush:
1239        sys.stdout.flush()
1240
1241
1242def printd(*strings, q=False):
1243    """
1244    Print debug information about the environment where the printd() is called.
1245    Local variables are printed out with their current values.
1246
1247    Use `q` to quit (exit) python session after the printd call.
1248    """
1249    from inspect import currentframe, getframeinfo
1250
1251    cf = currentframe().f_back
1252    cfi = getframeinfo(cf)
1253
1254    fname = os.path.basename(getframeinfo(cf).filename)
1255    print("\x1b[7m\x1b[3m\x1b[37m" + fname + " line:\x1b[1m" + str(cfi.lineno) + reset, end="")
1256    print("\x1b[3m\x1b[37m\x1b[2m", "\U00002501" * 30, time.ctime(), reset)
1257    if strings:
1258        print("    \x1b[37m\x1b[1mMessage : ", *strings)
1259    print("    \x1b[37m\x1b[1mFunction:\x1b[0m\x1b[37m " + str(cfi.function))
1260    print("    \x1b[1mLocals  :" + reset)
1261    for loc in cf.f_locals.keys():
1262        obj = cf.f_locals[loc]
1263        var = repr(obj)
1264        if 'module ' in var: continue
1265        if 'function ' in var: continue
1266        if 'class ' in var: continue
1267        if loc.startswith('_'): continue
1268        if hasattr(obj, 'name'):
1269            if not obj.name:
1270                oname = str(type(obj))
1271            else:
1272                oname = obj.name
1273            var = oname + ", at " + vedo.utils.precision(obj.GetPosition(), 3)
1274
1275        var = var.replace("vtkmodules.", "")
1276        print("      \x1b[37m", loc, "\t\t=", var[:60].replace("\n", ""), reset)
1277        if vedo.utils.is_sequence(obj) and len(obj) > 4:
1278            print('           \x1b[37m\x1b[2m\x1b[3m len:', len(obj),
1279                  ' min:', vedo.utils.precision(min(obj), 4),
1280                  ' max:', vedo.utils.precision(max(obj), 4),
1281                  reset)
1282
1283    if q:
1284        print(f"    \x1b[1m\x1b[37mExiting python now (q={bool(q)}).\x1b[0m\x1b[37m")
1285        sys.exit(0)
1286    sys.stdout.flush()
def printc( *strings, c=None, bc=None, bold=True, italic=False, blink=False, underline=False, strike=False, dim=False, invert=False, box='', end='\n', flush=True):
1074def printc(
1075    *strings,
1076    c=None,
1077    bc=None,
1078    bold=True,
1079    italic=False,
1080    blink=False,
1081    underline=False,
1082    strike=False,
1083    dim=False,
1084    invert=False,
1085    box="",
1086    end="\n",
1087    flush=True,
1088):
1089    """
1090    Print to terminal in color (any color!).
1091
1092    Arguments:
1093        c : (color)
1094            foreground color name or (r,g,b)
1095        bc : (color)
1096            background color name or (r,g,b)
1097        bold : (bool)
1098            boldface [True]
1099        italic : (bool)
1100            italic [False]
1101        blink : (bool)
1102            blinking text [False]
1103        underline : (bool)
1104            underline text [False]
1105        strike : (bool)
1106            strike through text [False]
1107        dim : (bool)
1108            make text look dimmer [False]
1109        invert : (bool)
1110            invert background and forward colors [False]
1111        box : (bool)
1112            print a box with specified text character ['']
1113        flush : (bool)
1114            flush buffer after printing [True]
1115        end : (str)
1116            the end character to be printed [newline]
1117
1118    Example:
1119        ```python
1120        from vedo.colors import printc
1121        printc('anything', c='tomato', bold=False, end=' ')
1122        printc('anything', 455.5, c='lightblue')
1123        printc(299792.48, c=4)
1124        ```
1125
1126    Examples:
1127        - [printc.py](https://github.com/marcomusy/vedo/tree/master/examples/other/printc.py)
1128
1129        ![](https://user-images.githubusercontent.com/32848391/50739010-2bfc2b80-11da-11e9-94de-011e50a86e61.jpg)
1130    """
1131
1132    if not vedo.settings.enable_print_color or not _terminal_has_colors:
1133        print(*strings, end=end, flush=flush)
1134        return
1135
1136    try:  # -------------------------------------------------------------
1137
1138        txt = str()
1139        ns = len(strings) - 1
1140        separator = " "
1141        offset = 0
1142        for i, s in enumerate(strings):
1143            if i == ns:
1144                separator = ""
1145            if ":" in repr(s):
1146                for k in emoji:
1147                    if k in str(s):
1148                        s = s.replace(k, emoji[k])
1149                        offset += 1
1150                for k, rp in vedo.shapes._reps:  # check symbols in shapes._reps
1151                    if k in str(s):
1152                        s = s.replace(k, rp)
1153                        offset += 1
1154
1155            txt += str(s) + separator
1156
1157        special, cseq = "", ""
1158        oneletter_colors = {
1159            "k": "\u001b[30m",  # because these are supported by most terminals
1160            "r": "\u001b[31m",
1161            "g": "\u001b[32m",
1162            "y": "\u001b[33m",
1163            "b": "\u001b[34m",
1164            "m": "\u001b[35m",
1165            "c": "\u001b[36m",
1166            "w": "\u001b[37m",
1167        }
1168
1169        if c is not None:
1170            if c is True:
1171                c = "g"
1172            elif c is False:
1173                c = "r"
1174
1175            if isinstance(c, str) and c in oneletter_colors:
1176                cseq += oneletter_colors[c]
1177            else:
1178                r, g, b = get_color(c)  # not all terms support this syntax
1179                cseq += f"\x1b[38;2;{int(r*255)};{int(g*255)};{int(b*255)}m"
1180
1181        if bc:
1182            if bc in oneletter_colors:
1183                cseq += oneletter_colors[bc]
1184            else:
1185                r, g, b = get_color(bc)
1186                cseq += f"\x1b[48;2;{int(r*255)};{int(g*255)};{int(b*255)}m"
1187
1188        if box is True:
1189            box = "-"
1190        if underline and not box:
1191            special += "\x1b[4m"
1192        if strike and not box:
1193            special += "\x1b[9m"
1194        if dim:
1195            special += "\x1b[2m"
1196        if invert:
1197            special += "\x1b[7m"
1198        if bold:
1199            special += "\x1b[1m"
1200        if italic:
1201            special += "\x1b[3m"
1202        if blink:
1203            special += "\x1b[5m"
1204
1205        if box and "\n" not in txt:
1206            box = box[0]
1207            boxv = box
1208            if box in ["_", "=", "-", "+", "~"]:
1209                boxv = "|"
1210
1211            if box in ("_", "."):
1212                outtxt = special + cseq + " " + box * (len(txt) + offset + 2) + " \n"
1213                outtxt += boxv + " " * (len(txt) + 2) + boxv + "\n"
1214            else:
1215                outtxt = special + cseq + box * (len(txt) + offset + 4) + "\n"
1216
1217            outtxt += boxv + " " + txt + " " + boxv + "\n"
1218
1219            if box == "_":
1220                outtxt += "|" + box * (len(txt) + offset + 2) + "|" + reset + end
1221            else:
1222                outtxt += box * (len(txt) + offset + 4) + reset + end
1223
1224            sys.stdout.write(outtxt)
1225
1226        else:
1227
1228            out = special + cseq + txt + reset
1229            sys.stdout.write(out + end)
1230
1231    except:  # ------------------------------------------------------------- fallback
1232
1233        try:
1234            print(*strings, end=end)
1235        except UnicodeEncodeError as e:
1236            print(e, end=end)
1237            pass
1238
1239    if flush:
1240        sys.stdout.flush()

Print to terminal in color (any color!).

Arguments:
  • c : (color) foreground color name or (r,g,b)
  • bc : (color) background color name or (r,g,b)
  • bold : (bool) boldface [True]
  • italic : (bool) italic [False]
  • blink : (bool) blinking text [False]
  • underline : (bool) underline text [False]
  • strike : (bool) strike through text [False]
  • dim : (bool) make text look dimmer [False]
  • invert : (bool) invert background and forward colors [False]
  • box : (bool) print a box with specified text character ['']
  • flush : (bool) flush buffer after printing [True]
  • end : (str) the end character to be printed [newline]
Example:
from vedo.colors import printc
printc('anything', c='tomato', bold=False, end=' ')
printc('anything', 455.5, c='lightblue')
printc(299792.48, c=4)
Examples:

def printd(*strings, q=False):
1243def printd(*strings, q=False):
1244    """
1245    Print debug information about the environment where the printd() is called.
1246    Local variables are printed out with their current values.
1247
1248    Use `q` to quit (exit) python session after the printd call.
1249    """
1250    from inspect import currentframe, getframeinfo
1251
1252    cf = currentframe().f_back
1253    cfi = getframeinfo(cf)
1254
1255    fname = os.path.basename(getframeinfo(cf).filename)
1256    print("\x1b[7m\x1b[3m\x1b[37m" + fname + " line:\x1b[1m" + str(cfi.lineno) + reset, end="")
1257    print("\x1b[3m\x1b[37m\x1b[2m", "\U00002501" * 30, time.ctime(), reset)
1258    if strings:
1259        print("    \x1b[37m\x1b[1mMessage : ", *strings)
1260    print("    \x1b[37m\x1b[1mFunction:\x1b[0m\x1b[37m " + str(cfi.function))
1261    print("    \x1b[1mLocals  :" + reset)
1262    for loc in cf.f_locals.keys():
1263        obj = cf.f_locals[loc]
1264        var = repr(obj)
1265        if 'module ' in var: continue
1266        if 'function ' in var: continue
1267        if 'class ' in var: continue
1268        if loc.startswith('_'): continue
1269        if hasattr(obj, 'name'):
1270            if not obj.name:
1271                oname = str(type(obj))
1272            else:
1273                oname = obj.name
1274            var = oname + ", at " + vedo.utils.precision(obj.GetPosition(), 3)
1275
1276        var = var.replace("vtkmodules.", "")
1277        print("      \x1b[37m", loc, "\t\t=", var[:60].replace("\n", ""), reset)
1278        if vedo.utils.is_sequence(obj) and len(obj) > 4:
1279            print('           \x1b[37m\x1b[2m\x1b[3m len:', len(obj),
1280                  ' min:', vedo.utils.precision(min(obj), 4),
1281                  ' max:', vedo.utils.precision(max(obj), 4),
1282                  reset)
1283
1284    if q:
1285        print(f"    \x1b[1m\x1b[37mExiting python now (q={bool(q)}).\x1b[0m\x1b[37m")
1286        sys.exit(0)
1287    sys.stdout.flush()

Print debug information about the environment where the printd() is called. Local variables are printed out with their current values.

Use q to quit (exit) python session after the printd call.

def get_color(rgb=None, hsv=None):
714def get_color(rgb=None, hsv=None):
715    """
716    Convert a color or list of colors to (r,g,b) format from many different input formats.
717
718    Set `hsv` to input as (hue, saturation, value).
719
720    Example:
721         - `RGB    = (255, 255, 255)` corresponds to white
722         - `rgb    = (1,1,1)` is again white
723         - `hex    = #FFFF00` is yellow
724         - `string = 'white'`
725         - `string = 'w'` is white nickname
726         - `string = 'dr'` is darkred
727         - `string = 'red4'` is a shade of red
728         - `int    =  7` picks color nr. 7 in a predefined color list
729         - `int    = -7` picks color nr. 7 in a different predefined list
730
731
732    Examples:
733        - [colorcubes.py](https://github.com/marcomusy/vedo/tree/master/examples/basic/colorcubes.py)
734
735            ![](https://vedo.embl.es/images/basic/colorcubes.png)
736    """
737    # recursion, return a list if input is list of colors:
738    if _is_sequence(rgb) and (len(rgb) > 3 or _is_sequence(rgb[0])):
739        seqcol = []
740        for sc in rgb:
741            seqcol.append(get_color(sc))
742        return seqcol
743
744    # because they are most common:
745    if isinstance(rgb, str):
746        if rgb == "r":
747            return (0.9960784313725, 0.11764705882352, 0.121568627450980)
748        elif rgb == "g":
749            return (0.0156862745098, 0.49803921568627, 0.062745098039215)
750        elif rgb == "b":
751            return (0.0588235294117, 0.0, 0.984313725490196)
752
753    if str(rgb).isdigit():
754        rgb = int(rgb)
755
756    if hsv:
757        c = hsv2rgb(hsv)
758    else:
759        c = rgb
760
761    if _is_sequence(c):
762        if c[0] <= 1 and c[1] <= 1 and c[2] <= 1:
763            return c  # already rgb
764        if len(c) == 3:
765            return list(np.array(c) / 255.0)  # RGB
766        return (c[0] / 255.0, c[1] / 255.0, c[2] / 255.0, c[3])  # RGBA
767
768    elif isinstance(c, str):  # is string
769        c = c.replace("grey", "gray").replace(" ", "")
770        if 0 < len(c) < 3:  # single/double letter color
771            if c.lower() in color_nicks:
772                c = color_nicks[c.lower()]
773            else:
774                vedo.logger.warning(
775                    f"Unknown color nickname {c}\nAvailable abbreviations: {color_nicks}"
776                )
777                return (0.5, 0.5, 0.5)
778
779        if c.lower() in colors:  # matplotlib name color
780            c = colors[c.lower()]
781            # from now format is hex!
782
783        if c.startswith("#"):  # hex to rgb
784            h = c.lstrip("#")
785            rgb255 = list(int(h[i : i + 2], 16) for i in (0, 2, 4))
786            rgbh = np.array(rgb255) / 255.0
787            if np.sum(rgbh) > 3:
788                vedo.logger.error(f"in get_color(): Wrong hex color {c}")
789                return (0.5, 0.5, 0.5)
790            return tuple(rgbh)
791
792        else:  # vtk name color
793            namedColors = vtk.vtkNamedColors()
794            rgba = [0, 0, 0, 0]
795            namedColors.GetColor(c, rgba)
796            return (rgba[0] / 255.0, rgba[1] / 255.0, rgba[2] / 255.0)
797
798    elif isinstance(c, (int, float)):  # color number
799        return palettes[vedo.settings.palette % len(palettes)][abs(int(c)) % 10]
800
801    return (0.5, 0.5, 0.5)

Convert a color or list of colors to (r,g,b) format from many different input formats.

Set hsv to input as (hue, saturation, value).

Example:
  • RGB = (255, 255, 255) corresponds to white
  • rgb = (1,1,1) is again white
  • hex = #FFFF00 is yellow
  • string = 'white'
  • string = 'w' is white nickname
  • string = 'dr' is darkred
  • string = 'red4' is a shade of red
  • int = 7 picks color nr. 7 in a predefined color list
  • int = -7 picks color nr. 7 in a different predefined list
Examples:
def get_color_name(c):
804def get_color_name(c):
805    """Find the name of the closest color."""
806    c = np.array(get_color(c))  # reformat to rgb
807    mdist = 99.0
808    kclosest = ""
809    for key in colors:
810        ci = np.array(get_color(key))
811        d = np.linalg.norm(c - ci)
812        if d < mdist:
813            mdist = d
814            kclosest = str(key)
815    return kclosest

Find the name of the closest color.

def color_map(value, name='jet', vmin=None, vmax=None):
847def color_map(value, name="jet", vmin=None, vmax=None):
848    """
849    Map a real value in range [vmin, vmax] to a (r,g,b) color scale.
850
851    Return the (r,g,b) color, or a list of (r,g,b) colors.
852
853    Arguments:
854        value : *(float, list)*
855            scalar value to transform into a color
856        name : *(str, matplotlib.colors.LinearSegmentedColormap)*
857            color map name
858
859    Very frequently used color maps are:
860
861        ![](https://user-images.githubusercontent.com/32848391/50738804-577e1680-11d8-11e9-929e-fca17a8ac6f3.jpg)
862
863    A more complete color maps list:
864
865        ![](https://matplotlib.org/1.2.1/_images/show_colormaps.png)
866
867    .. note:: Can also directly use and customize a matplotlib color map
868
869    Example:
870        ```python
871        from vedo import color_map
872        import matplotlib.cm as cm
873        print( color_map(0.2, cm.flag, 0, 1) )
874        # (1.0, 0.809016994374948, 0.6173258487801733)
875        ```
876
877    Examples:
878        - [plot_bars.py](https://github.com/marcomusy/vedo/tree/master/examples/pyplot/plot_bars.py)
879
880            <img src="https://vedo.embl.es/images/pyplot/plot_bars.png" width="400"/>
881
882    """
883    cut = _is_sequence(value)  # to speed up later
884
885    if cut:
886        values = np.asarray(value)
887        if vmin is None:
888            vmin = np.min(values)
889        if vmax is None:
890            vmax = np.max(values)
891        values = np.clip(values, vmin, vmax)
892        values = (values - vmin) / (vmax - vmin)
893    else:
894        if vmin is None:
895            vedo.logger.warning("in color_map() you must specify vmin! Assume 0.")
896            vmin = 0
897        if vmax is None:
898            vedo.logger.warning("in color_map() you must specify vmax! Assume 1.")
899            vmax = 1
900        values = [(value - vmin) / (vmax - vmin)]
901
902    if _has_matplotlib:
903        # matplotlib is available, use it! ###########################
904        if isinstance(name, str):
905            mp = _cm_mpl.get_cmap(name=name)
906        else:
907            mp = name  # assume matplotlib.colors.LinearSegmentedColormap
908        result = mp(values)[:, [0, 1, 2]]
909
910    else:
911        # matplotlib not available ###################################
912        invert = False
913        if name.endswith("_r"):
914            invert = True
915            name = name.replace("_r", "")
916        try:
917            cmap = cmaps[name]
918        except KeyError:
919            vedo.logger.error(f"in color_map(), no color map with name {name} or {name}_r")
920            vedo.logger.error(f"Available color maps are:\n{cmaps.keys()}")
921            return np.array([0.5, 0.5, 0.5])
922
923        result = []
924        n = len(cmap) - 1
925        for v in values:
926            iv = int(v * n)
927            if invert:
928                iv = n - iv
929            rgb = hex2rgb(cmap[iv])
930            result.append(rgb)
931        result = np.array(result)
932
933    if cut:
934        return result
935    return result[0]

Map a real value in range [vmin, vmax] to a (r,g,b) color scale.

Return the (r,g,b) color, or a list of (r,g,b) colors.

Arguments:
  • value : (float, list) scalar value to transform into a color
  • name : (str, matplotlib.colors.LinearSegmentedColormap) color map name
Very frequently used color maps are:

A more complete color maps list:

Can also directly use and customize a matplotlib color map
Example:
from vedo import color_map
import matplotlib.cm as cm
print( color_map(0.2, cm.flag, 0, 1) )
# (1.0, 0.809016994374948, 0.6173258487801733)
Examples:
def build_palette(color1, color2, n, hsv=True):
938def build_palette(color1, color2, n, hsv=True):
939    """
940    Generate N colors starting from `color1` to `color2`
941    by linear interpolation in HSV or RGB spaces.
942
943    Arguments:
944        N : (int)
945            number of output colors.
946        color1 : (color)
947            first color.
948        color2 : (color)
949            second color.
950        hsv : (bool)
951            if `False`, interpolation is calculated in RGB space.
952
953    Examples:
954        - [mesh_custom.py](https://github.com/marcomusy/vedo/tree/master/examples/basic/mesh_custom.py)
955
956            ![](https://vedo.embl.es/images/basic/mesh_custom.png)
957    """
958    if hsv:
959        color1 = rgb2hsv(color1)
960        color2 = rgb2hsv(color2)
961    c1 = np.array(get_color(color1))
962    c2 = np.array(get_color(color2))
963    cols = []
964    for f in np.linspace(0, 1, n, endpoint=True):
965        c = c1 * (1 - f) + c2 * f
966        if hsv:
967            c = np.array(hsv2rgb(c))
968        cols.append(c)
969    return np.array(cols)

Generate N colors starting from color1 to color2 by linear interpolation in HSV or RGB spaces.

Arguments:
  • N : (int) number of output colors.
  • color1 : (color) first color.
  • color2 : (color) second color.
  • hsv : (bool) if False, interpolation is calculated in RGB space.
Examples:
def build_lut( colorlist, vmin=None, vmax=None, below_color=None, above_color=None, nan_color=None, below_alpha=1, above_alpha=1, nan_alpha=1, interpolate=False):
 972def build_lut(
 973    colorlist,
 974    vmin=None,
 975    vmax=None,
 976    below_color=None,
 977    above_color=None,
 978    nan_color=None,
 979    below_alpha=1,
 980    above_alpha=1,
 981    nan_alpha=1,
 982    interpolate=False,
 983):
 984    """
 985    Generate colors in a lookup table (LUT).
 986
 987    Return the `vtkLookupTable` object. This can be fed into `cmap()` method.
 988
 989    Arguments:
 990        colorlist : (list)
 991            a list in the form `[(scalar1, [r,g,b]), (scalar2, 'blue'), ...]`.
 992        vmin : (float)
 993            specify minimum value of scalar range
 994        vmax : (float)
 995            specify maximum value of scalar range
 996        below_color : (color)
 997            color for scalars below the minimum in range
 998        below_alpha : (float)
 999            opacity for scalars below the minimum in range
1000        above_color : (color)
1001            color for scalars above the maximum in range
1002        above_alpha : (float)
1003            alpha for scalars above the maximum in range
1004        nan_color : (color)
1005            color for invalid (nan) scalars
1006        nan_alpha : (float)
1007            alpha for invalid (nan) scalars
1008        interpolate : (bool)
1009            interpolate or not intermediate scalars
1010
1011    Examples:
1012        - [mesh_lut.py](https://github.com/marcomusy/vedo/tree/master/examples/basic/mesh_lut.py)
1013
1014            ![](https://vedo.embl.es/images/basic/mesh_lut.png)
1015    """
1016    ctf = vtk.vtkColorTransferFunction()
1017    ctf.SetColorSpaceToRGB()
1018    ctf.SetScaleToLinear()
1019    alpha_x, alpha_vals = [], []
1020    for sc in colorlist:
1021        if len(sc) >= 3:
1022            scalar, col, alf = sc[:3]
1023        else:
1024            alf = 1
1025            scalar, col = sc
1026        r, g, b = get_color(col)
1027        ctf.AddRGBPoint(scalar, r, g, b)
1028        alpha_x.append(scalar)
1029        alpha_vals.append(alf)
1030
1031    lut = vtk.vtkLookupTable()
1032    lut.SetNumberOfTableValues(256)
1033
1034    x0, x1 = ctf.GetRange()  # range of the introduced values
1035    if vmin is not None:
1036        x0 = vmin
1037    if vmax is not None:
1038        x1 = vmax
1039    ctf.SetRange(x0, x1)
1040    lut.SetRange(x0, x1)
1041
1042    if below_color is not None:
1043        lut.SetBelowRangeColor(list(get_color(below_color)) + [below_alpha])
1044        lut.SetUseBelowRangeColor(True)
1045    if above_color is not None:
1046        lut.SetAboveRangeColor(list(get_color(above_color)) + [above_alpha])
1047        lut.SetUseAboveRangeColor(True)
1048    if nan_color is not None:
1049        lut.SetNanColor(list(get_color(nan_color)) + [nan_alpha])
1050
1051    rgba = (1, 1, 1, 1)
1052    for i in range(256):
1053        p = i / 255
1054        x = (1 - p) * x0 + p * x1
1055        if interpolate:
1056            alf = np.interp(x, alpha_x, alpha_vals)
1057            rgba = list(ctf.GetColor(x)) + [alf]
1058        else:
1059            for c in colorlist:
1060                if x <= c[0]:
1061                    if len(c) == 3:
1062                        alf = c[2]
1063                    else:
1064                        alf = 1
1065                    rgba = list(get_color(c[1])) + [alf]
1066                    break
1067        lut.SetTableValue(i, rgba)
1068
1069    lut.Build()
1070    return lut

Generate colors in a lookup table (LUT).

Return the vtkLookupTable object. This can be fed into cmap() method.

Arguments:
  • colorlist : (list) a list in the form [(scalar1, [r,g,b]), (scalar2, 'blue'), ...].
  • vmin : (float) specify minimum value of scalar range
  • vmax : (float) specify maximum value of scalar range
  • below_color : (color) color for scalars below the minimum in range
  • below_alpha : (float) opacity for scalars below the minimum in range
  • above_color : (color) color for scalars above the maximum in range
  • above_alpha : (float) alpha for scalars above the maximum in range
  • nan_color : (color) color for invalid (nan) scalars
  • nan_alpha : (float) alpha for invalid (nan) scalars
  • interpolate : (bool) interpolate or not intermediate scalars
Examples: