Skip to content

Commit

Permalink
Added trace line and marker outline options (#373)
Browse files Browse the repository at this point in the history
Co-authored-by: Guillaume Fraux <[email protected]>
  • Loading branch information
ceriottm and Luthaf authored Oct 9, 2024
1 parent 15b7f56 commit 73c422e
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 46 deletions.
47 changes: 27 additions & 20 deletions python/chemiscope/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,43 +617,50 @@ def quick_settings(
:param str symbol: The (categorical) property to use to determine point markers.
:param bool trajectory: A boolean flag that sets some default options suitable
to view trajectory data.
:param bool trajectory: A boolean flag that sets some default options suitable to
view trajectory data: fixing the viewpoint for the structure, reducing the delay
when cycling between structures and adding a line joining the points in the map.
:param dict map_settings: Additional settings for the map (following the
chemiscope settings schema).
:param dict map_settings: Additional settings for the map (following the chemiscope
settings schema).
:param dict structure_settings: Additional settings for the
structure viewer (following the chemiscope settings schema).
:param dict structure_settings: Additional settings for the structure viewer
(following the chemiscope settings schema).
"""

if map_settings is None:
map_settings = {}

if structure_settings is None:
structure_settings = {}

map_settings.update(
{
if (x + y + z + color + size + symbol) == "":
# if at least one of the properties is requested
computed_map_settings = {}
else:
computed_map_settings = {
"x": {"property": x},
"y": {"property": y},
"z": {"property": z},
"color": {"property": color},
"size": {"property": size},
"symbol": symbol,
}
)

structure_settings.update(
computed_map_settings.update(
{
"keepOrientation": trajectory,
"playbackDelay": 10 if trajectory else 700,
"joinPoints": trajectory,
}
)

computed_structure_settings = {
"keepOrientation": trajectory,
"playbackDelay": 10 if trajectory else 700,
}

if map_settings is not None:
computed_map_settings.update(map_settings)

if structure_settings is not None:
computed_structure_settings.update(structure_settings)

return {
"map": map_settings,
"structure": [structure_settings],
"map": computed_map_settings,
"structure": [computed_structure_settings],
}


Expand Down
5 changes: 4 additions & 1 deletion python/examples/3-trajectory.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@
"playbackDelay": 100,
"shape": "forces", # visualize force vectors
}
]
],
"map": {
"joinPoints": True,
},
},
)

Expand Down
41 changes: 19 additions & 22 deletions src/map/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,8 @@ export class PropertiesMap {
color: this._colors(0)[0],
coloraxis: 'coloraxis',
line: {
color: this._lineColors(0)[0],
width: 1,
color: 'black',
width: this._options.markerOutline.value ? 0.5 : 0,
},
// prevent plolty from messing with opacity when doing bubble
// style charts (different sizes for each point)
Expand All @@ -545,7 +545,13 @@ export class PropertiesMap {
sizemode: 'area',
symbol: this._symbols(0)[0],
},
mode: 'markers',
line: {
// lines type (if required)
color: 'black',
width: 0.5,
dash: 'solid',
},
mode: this._options.joinPoints.value ? 'lines+markers' : 'markers',
showlegend: false,
};

Expand Down Expand Up @@ -1158,6 +1164,16 @@ export class PropertiesMap {
this._options.size.mode.onchange.push(() => {
this._restyle({ 'marker.size': this._sizes(0) } as Data, 0);
});

this._options.markerOutline.onchange.push(() => {
const width = this._options.markerOutline.value ? 0.5 : 0;
this._restyle({ 'marker.line.width': width } as Data, [0]);
});

this._options.joinPoints.onchange.push(() => {
const mode = this._options.joinPoints.value ? 'lines+markers' : 'markers';
this._restyle({ mode: mode } as Data, [0]);
});
}

/** Actually create the Plotly plot */
Expand Down Expand Up @@ -1391,18 +1407,6 @@ export class PropertiesMap {
return this._selectTrace<Array<string | number>>(values, selected, trace);
}

/**
* Get the **line** color values to use with the given plotly `trace`, or
* all of them if `trace === undefined`
*/
private _lineColors(trace?: number): string[] {
if (this._is3D()) {
return this._selectTrace<string>('black', 'black', trace);
} else {
return this._selectTrace<string>('rgba(1, 1, 1, 0.3)', 'black', trace);
}
}

/**
* Get the values to use as marker size with the given plotly `trace`, or
* all of them if `trace === undefined`.
Expand Down Expand Up @@ -1549,10 +1553,6 @@ export class PropertiesMap {
// Change the data that vary between 2D and 3D mode
this._restyle(
{
// transparency messes with depth sorting in 3D mode, even with
// line width set to 0 ¯\_(ツ)_/¯
// https://github.com/plotly/plotly.js/issues/4111
'marker.line.color': this._lineColors(),
'marker.line.width': [1, 2],
// size change from 2D to 3D
'marker.size': this._sizes(),
Expand Down Expand Up @@ -1594,9 +1594,6 @@ export class PropertiesMap {

this._restyle(
{
// transparency messes with depth sorting in 3D mode
// https://github.com/plotly/plotly.js/issues/4111
'marker.line.color': this._lineColors(),
'marker.line.width': [1, 0],
// size change from 2D to 3D
'marker.size': this._sizes(),
Expand Down
16 changes: 15 additions & 1 deletion src/map/options.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@

<div style="margin-bottom: 1.5em"></div>
<h5 class="chsp-settings-section-title">Style</h5>

<div class="input-group chsp-map-extra-options" style="margin-bottom: 0.6em">
<div class="form-check form-switch">
<input class="form-check-input" id="map-marker-outline" type="checkbox" />
<label class="form-check-label" for="map-marker-outline" title="show point outlines">show outlines</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" id="map-join-points" type="checkbox" />
<label class="form-check-label" for="map-join-points" title="draw a line through the points, sequentially">link points</label>
</div>
</div>

<div class="chsp-map-options">
<div class="input-group input-group-sm">
<label class="input-group-text" for="map-color-property">color:</label>
Expand Down Expand Up @@ -171,7 +183,9 @@
<label class="input-group-text" for="map-size-transform">transform:</label>
<select id="map-size-transform" class="form-select">
<option value="linear" title="Linear mapping over the full range of values (large value -> large size)">linear</option>
<option value="flip-linear" title="Linear reverse mapping over the full range of values (large value -> small size)">flipped linear</option>
<option value="flip-linear" title="Linear reverse mapping over the full range of values (large value -> small size)">
flipped linear
</option>
<option value="proportional" title="Proportional to actual value, breaks for negative values">proportional</option>
<option value="log" title="Log-scale of actual value, breaks for negative values">log</option>
<option value="sqrt" title="Square-root of actual value, breaks for negative values">sqrt</option>
Expand Down
13 changes: 11 additions & 2 deletions src/map/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ export class MapOptions extends OptionsGroup {
mode: HTMLOption<'string'>;
property: HTMLOption<'string'>;
};
public markerOutline: HTMLOption<'boolean'>;
public joinPoints: HTMLOption<'boolean'>;

/// The HTML button to open the settings modal
private _openModal: HTMLElement;
Expand Down Expand Up @@ -149,6 +151,10 @@ export class MapOptions extends OptionsGroup {
'mode'
);

// outline and line
this.markerOutline = new HTMLOption('boolean', true);
this.joinPoints = new HTMLOption('boolean', false);

// Setup default values
this.x.property.value = propertiesName[0];
this.y.property.value = propertiesName[1];
Expand Down Expand Up @@ -308,7 +314,7 @@ export class MapOptions extends OptionsGroup {
const { min, max } = arrayMaxMin(rawSizes);
const defaultSize = this.is3D() ? 800 : 300;
const bottomLimit = 0.1; // lower limit to prevent size of 0
const defaultScaled = 0.55;
const defaultScaled = 0.3;
const nonzeromin = min > 0 ? min : 1e-6 * (max - min); // non-zero minimum value for scales needing it
const values = rawSizes.map((v: number) => {
// normalize between 0 and 1, then scale by the user provided value
Expand Down Expand Up @@ -347,7 +353,7 @@ export class MapOptions extends OptionsGroup {
break;
default:
// corresponds to 'constant'
scaled = 0.55 - bottomLimit;
scaled = defaultScaled - bottomLimit;
break;
}
scaled = scaled + bottomLimit; // minimum size is enforced
Expand Down Expand Up @@ -544,6 +550,9 @@ export class MapOptions extends OptionsGroup {
this.size.property.bind(selectSizeProperty, 'value');
this.size.factor.bind(this.getModalElement('map-size-factor'), 'value');
this.size.mode.bind(this.getModalElement('map-size-transform'), 'value');
// ====== marker outline and line trace
this.markerOutline.bind(this.getModalElement('map-marker-outline'), 'checked');
this.joinPoints.bind(this.getModalElement('map-join-points'), 'checked');
}

/** Get the colorscale to use for markers in the main plotly trace */
Expand Down

0 comments on commit 73c422e

Please sign in to comment.