# ! pip install --user graphistry
import graphistry

# To specify Graphistry account & server, use:
# graphistry.register(api=3, username='...', password='...', protocol='https', server='hub.graphistry.com')
# For more options, see https://github.com/graphistry/pygraphistry#configure

graphistry.__version__

import datetime, pandas as pd
e_df = pd.DataFrame({
    's': ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'd', 'e'],
    'd': ['b', 'c', 'a', 'b', 'c', 'a', 'c', 'e', 'd'],
    'time': [datetime.datetime(1987, 10, 1), datetime.datetime(1987, 10, 2), datetime.datetime(1987, 10, 3),
             datetime.datetime(1988, 10, 1), datetime.datetime(1988, 10, 2), datetime.datetime(1988, 10, 3),
             datetime.datetime(1989, 10, 1), datetime.datetime(1989, 10, 2), datetime.datetime(1989, 10, 3)]
})
n_df = pd.DataFrame({
    'n': ['a', 'b', 'c', 'd', 'e'],
    'score': [ 1, 30, 50, 70, 90 ],
    'palette_color_int32': pd.Series(
        [0, 1, 2, 3, 4],
        dtype='int32'),
    'hex_color_int64': pd.Series(
        [0xFF000000, 0xFFFF0000, 0xFFFFFF00, 0x00FF0000, 0x0000FF00],
        dtype='int64'),
    'type': ['mac', 'macbook', 'mac', 'macbook', 'sheep']
})

g = graphistry.edges(e_df, 's', 'd').nodes(n_df, 'n')

"""
Explanation: Size encodings tutorial
See the examples below for common ways to map data to node size in Graphistry.
Size refers to point radius. This tutorial covers two kinds of size controls:

Node size setting, which is a global scaling factor
Node size encoding, used for mapping a node data column to size

Sizes are often used with node color, label, icon, and badges to provide more visual information. Most encodings work both for points and edges. The PyGraphistry Python client makes it easier to use the URL settings API and the REST upload API. For dynamic control, you can use also use the JavaScript APIs. 
Setup
Mode api=3 is recommended. It is required for complex_encodings (ex: .encode_point_size(...)). Mode api=1 works with the simpler .bind(point_size='col_a') form.
End of explanation
"""


g.plot()

"""
Explanation: Default Size
Graphistry uses the 'degree' of a node, so nodes with more edges appear bigger
End of explanation
"""


g.settings(url_params={'pointSize': 0.5}).plot()

"""
Explanation: Size Setting
You can tune the scaling factor:
End of explanation
"""


g.settings(url_params={'pointSize': 0.3}).encode_point_size('score').plot()

"""
Explanation: Size encodings
Options: continuous mapping, categorical mapping
Continuous size encodings
Use an input column as relative sizes. Graphistry automatically normalizes them.
End of explanation
"""


g.settings(url_params={'pointSize': 0.3})\
 .encode_point_size(
    'type',
    categorical_mapping={
        'mac': 50,
        'macbook': 100
    },
    default_mapping=20
).plot()

"""
Explanation: Categorical size encodings
Map distinct values to specific sizes. Optionally, set a default, else black.
End of explanation
"""


g.settings(url_params={'pointSize': 0.3})\
 .encode_point_size(
    'type',
    categorical_mapping={
        'mac': 50,
        'macbook': 100
    },
    default_mapping=20
).plot()

"""
Explanation: Legend support
Categorical node sizes will appear in legend when driven by column type:
End of explanation
"""


