Skip to content

Commit c1a4926

Browse files
Merge pull request #396 from plotly/add_geoscatter_functionality_in_fig2plotly
add geoscatter functionality in fig2plotly
2 parents 03f5ea4 + 49ce2b2 commit c1a4926

File tree

7 files changed

+318
-8
lines changed

7 files changed

+318
-8
lines changed

plotly/plotly_aux/plotly.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
offline_given = true;
5858
end
5959

60-
if offline_given
60+
if ~offline_given
6161
obj = plotlyfig(args, structargs);
6262
obj.layout.width = 840;
6363
obj.layout.height = 630;

plotly/plotlyfig.m

+2
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
obj.PlotlyDefaults.CaptionMarginIncreaseFactor = 1.2;
101101
obj.PlotlyDefaults.MinCaptionMargin = 80;
102102
obj.PlotlyDefaults.IsLight = false;
103+
obj.PlotlyDefaults.isGeoaxis = false;
103104

104105
%-State-%
105106
obj.State.Figure = [];
@@ -1060,6 +1061,7 @@ function delete(obj)
10601061
|| strcmpi(fieldname,'yaxis') || strcmpi(fieldname,'cone')...
10611062
|| strcmpi(fieldname,'legend') || strcmpi(fieldname,'histogram')...
10621063
|| strcmpi(fieldname,'scatter') || strcmpi(fieldname,'line')...
1064+
|| strcmpi(fieldname,'scattergeo') ...
10631065
)
10641066
fprintf(['\nWhoops! ' exception.message(1:end-1) ' in ' fieldname '\n\n']);
10651067
end

plotly/plotlyfig_aux/core/updateAxis.m

+14-6
Original file line numberDiff line numberDiff line change
@@ -61,20 +61,28 @@
6161
is_headmap_axis = isfield(axis_data, 'XDisplayData');
6262
obj.PlotOptions.is_headmap_axis = is_headmap_axis;
6363

64+
%-------------------------------------------------------------------------%
65+
66+
%-check if geo-axis-%
67+
isGeoaxis = isfield(axis_data, 'Type') && strcmpi(axis_data.Type, 'geoaxes');
68+
obj.PlotlyDefaults.isGeoaxis = isGeoaxis;
69+
70+
%-------------------------------------------------------------------------%
71+
6472
%-xaxis-%
65-
if ~is_headmap_axis
66-
xaxis = extractAxisData(obj,axis_data,'X');
73+
if is_headmap_axis
74+
xaxis = extractHeatmapAxisData(obj,axis_data, 'X');
6775
else
68-
xaxis = extractHeatmapAxisData(obj,axis_data,'X');
76+
xaxis = extractAxisData(obj,axis_data, 'X');
6977
end
7078

7179
%-------------------------------------------------------------------------%
7280

7381
%-yaxis-%
74-
if ~is_headmap_axis
75-
yaxis = extractAxisData(obj,axis_data,'Y');
82+
if is_headmap_axis
83+
yaxis = extractHeatmapAxisData(obj,axis_data, 'Y');
7684
else
77-
yaxis = extractHeatmapAxisData(obj,axis_data,'Y');
85+
yaxis = extractAxisData(obj,axis_data, 'Y');
7886
end
7987

8088
%-------------------------------------------------------------------------%

plotly/plotlyfig_aux/core/updateData.m

+7-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151

5252
switch lower(obj.State.Plot(dataIndex).Class)
5353

54+
%--GEOAXES SPECIAL CASE--%
55+
case 'geoaxes'
56+
UpdateGeoAxes(obj, dataIndex);
57+
5458
%--CORE PLOT OBJECTS--%
5559
case 'scatterhistogram'
5660
updateScatterhistogram(obj, dataIndex);
@@ -119,7 +123,9 @@
119123
updateQuivergroup(obj, dataIndex);
120124
case 'scatter'
121125
if strcmpi(obj.State.Axis(dataIndex).Handle.Type, 'polaraxes')
122-
updateScatterPolar(obj, dataIndex);
126+
updateScatterPolar(obj, dataIndex);
127+
elseif obj.PlotlyDefaults.isGeoaxis
128+
updateGeoScatter(obj, dataIndex);
123129
else
124130
updateScatter(obj, dataIndex);
125131
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
function UpdateGeoAxes(obj, geoIndex)
2+
3+
%-AXIS INDEX-%
4+
axIndex = obj.getAxisIndex(obj.State.Plot(geoIndex).AssociatedAxis);
5+
6+
%-GET DATA STRUCTURE- %
7+
geoData = get(obj.State.Plot(geoIndex).Handle);
8+
9+
%-CHECK FOR MULTIPLE AXES-%
10+
[xsource, ysource] = findSourceAxis(obj,axIndex);
11+
12+
%-------------------------------------------------------------------------%
13+
14+
%-set domain geo plot-%
15+
xo = geoData.Position(1);
16+
yo = geoData.Position(2);
17+
w = geoData.Position(3);
18+
h = geoData.Position(4);
19+
20+
geo.domain.x = min([xo xo + w],1);
21+
geo.domain.y = min([yo yo + h],1);
22+
23+
%-------------------------------------------------------------------------%
24+
25+
%-setting projection-%
26+
geo.projection.type = 'mercator';
27+
28+
%-------------------------------------------------------------------------%
29+
30+
%-setting basemap-%
31+
geo.framecolor = 'rgb(120,120,120)';
32+
33+
if strcmpi(geoData.Basemap, 'streets-light')
34+
geo.oceancolor = 'rgba(20,220,220,1)';
35+
geo.landcolor = 'rgba(20,220,220,0.2)';
36+
elseif strcmpi(geoData.Basemap, 'colorterrain')
37+
geo.oceancolor = 'rgba(118,165,225,0.6)';
38+
geo.landcolor = 'rgba(190,180,170,1)';
39+
geo.showcountries = true;
40+
geo.showlakes = true;
41+
end
42+
43+
geo.showocean = true;
44+
geo.showcoastlines = false;
45+
geo.showland = true;
46+
47+
%-------------------------------------------------------------------------%
48+
49+
%-setting latitude axis
50+
latTick = geoData.LatitudeAxis.TickValues;
51+
52+
geo.lataxis.range = geoData.LatitudeLimits;
53+
geo.lataxis.tick0 = latTick(1);
54+
geo.lataxis.dtick = mean(diff(latTick));
55+
56+
if strcmpi(geoData.Grid, 'on')
57+
geo.lataxis.showgrid = true;
58+
geo.lataxis.gridwidth = geoData.LineWidth;
59+
geo.lataxis.gridcolor = sprintf('rgba(%f,%f,%f,%f)', 255*geoData.GridColor, geoData.GridAlpha);
60+
end
61+
62+
%-------------------------------------------------------------------------%
63+
64+
%-setting longitude axis
65+
lonTick = geoData.LongitudeAxis.TickValues;
66+
67+
geo.lonaxis.range = geoData.LongitudeLimits;
68+
geo.lonaxis.tick0 = lonTick(1);
69+
geo.lonaxis.dtick = mean(diff(lonTick));
70+
71+
if strcmpi(geoData.Grid, 'on')
72+
geo.lonaxis.showgrid = true;
73+
geo.lonaxis.gridwidth = geoData.LineWidth;
74+
geo.lonaxis.gridcolor = sprintf('rgba(%f,%f,%f,%f)', 255*geoData.GridColor, geoData.GridAlpha);
75+
end
76+
77+
%-------------------------------------------------------------------------%
78+
79+
%-set geo axes to layout-%
80+
81+
obj.layout = setfield(obj.layout, sprintf('geo%d', xsource+1), geo);
82+
83+
%-------------------------------------------------------------------------%
84+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
function updateGeoScatter(obj,geoIndex)
2+
3+
%-AXIS INDEX-%
4+
axIndex = obj.getAxisIndex(obj.State.Plot(geoIndex).AssociatedAxis);
5+
6+
%-GET STRUCTURES-%
7+
geoData = get(obj.State.Plot(geoIndex).Handle);
8+
axisData = geoData.Parent;
9+
figureData = get(obj.State.Figure.Handle);
10+
11+
%-CHECK FOR MULTIPLE AXES-%
12+
[xsource, ysource] = findSourceAxis(obj,axIndex);
13+
14+
%-ASSOCIATE GEO-AXES LAYOUT-%
15+
obj.data{geoIndex}.geo = sprintf('geo%d', xsource+1);
16+
17+
%-------------------------------------------------------------------------%
18+
19+
%-set scattergeo type-%
20+
obj.data{geoIndex}.type = 'scattergeo';
21+
22+
%-------------------------------------------------------------------------%
23+
24+
%-set scattergeo mode-%
25+
obj.data{geoIndex}.mode = 'markers';
26+
27+
%-------------------------------------------------------------------------%
28+
29+
%-set plot data-%
30+
obj.data{geoIndex}.lat = geoData.LatitudeData;
31+
obj.data{geoIndex}.lon = geoData.LongitudeData;
32+
33+
%-------------------------------------------------------------------------%
34+
35+
%-get marker setting-%
36+
marker = extractGeoMarker(geoData, axisData);
37+
38+
%-------------------------------------------------------------------------%
39+
40+
%-set marker field-%
41+
obj.data{geoIndex}.marker = marker;
42+
43+
%-------------------------------------------------------------------------%
44+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
function marker = extractGeoMarker(geoData, axisData)
2+
3+
%-------------------------------------------------------------------------%
4+
5+
%-FIGURE STRUCTURE-%
6+
figureData = get(ancestor(geoData.Parent,'figure'));
7+
8+
%-INITIALIZE OUTPUT-%
9+
marker = struct();
10+
11+
%-------------------------------------------------------------------------%
12+
13+
%-MARKER SIZEREF-%
14+
marker.sizeref = 1;
15+
16+
%-------------------------------------------------------------------------%
17+
18+
%-MARKER SIZEMODE-%
19+
marker.sizemode = 'area';
20+
21+
%-------------------------------------------------------------------------%
22+
23+
%-MARKER SIZE (STYLE)-%
24+
marker.size = geoData.SizeData;
25+
26+
%-------------------------------------------------------------------------%
27+
28+
%-MARKER SYMBOL (STYLE)-%
29+
if ~strcmp(geoData.Marker,'none')
30+
31+
switch geoData.Marker
32+
case '.'
33+
marksymbol = 'circle';
34+
case 'o'
35+
marksymbol = 'circle';
36+
case 'x'
37+
marksymbol = 'x-thin-open';
38+
case '+'
39+
marksymbol = 'cross-thin-open';
40+
case '*'
41+
marksymbol = 'asterisk-open';
42+
case {'s','square'}
43+
marksymbol = 'square';
44+
case {'d','diamond'}
45+
marksymbol = 'diamond';
46+
case 'v'
47+
marksymbol = 'triangle-down';
48+
case '^'
49+
marksymbol = 'star-triangle-up';
50+
case '<'
51+
marksymbol = 'triangle-left';
52+
case '>'
53+
marksymbol = 'triangle-right';
54+
case {'p','pentagram'}
55+
marksymbol = 'star';
56+
case {'h','hexagram'}
57+
marksymbol = 'hexagram';
58+
end
59+
60+
marker.symbol = marksymbol;
61+
end
62+
63+
%-------------------------------------------------------------------------%
64+
65+
%-MARKER LINE WIDTH (STYLE)-%
66+
marker.line.width = 2*geoData.LineWidth;
67+
68+
%-------------------------------------------------------------------------%
69+
70+
%--MARKER FILL COLOR--%
71+
72+
% marker face color
73+
faceColor = geoData.MarkerFaceColor;
74+
75+
filledMarkerSet = {'o','square','s','diamond','d','v','^', '<','>','hexagram','pentagram'};
76+
filledMarker = ismember(geoData.Marker, filledMarkerSet);
77+
78+
if filledMarker
79+
80+
if isnumeric(faceColor)
81+
markerColor = sprintf('rgb(%f,%f,%f)', 255 * faceColor);
82+
83+
else
84+
85+
switch faceColor
86+
87+
case 'none'
88+
89+
markerColor = 'rgba(0,0,0,0)';
90+
91+
case 'auto'
92+
93+
if ~strcmp(axisData.Color,'none')
94+
col = 255*axisData.Color;
95+
else
96+
col = 255*figureData.Color;
97+
end
98+
99+
markerColor = sprintf('rgb(%f,%f,%f)', col);
100+
101+
case 'flat'
102+
103+
cData = geoData.CData;
104+
cMap = figureData.Colormap;
105+
ncolors = size(cMap, 1);
106+
107+
for m = 1:length(cData)
108+
colorValue = max( min( cData(m), axisData.CLim(2) ), axisData.CLim(1) );
109+
scaleFactor = (colorValue - axisData.CLim(1)) / diff(axisData.CLim);
110+
rgbColor = 255 * cMap( 1+floor(scaleFactor*(ncolors-1)), : );
111+
markerColor{m} = sprintf('rgb(%f,%f,%f)', rgbColor);
112+
end
113+
end
114+
end
115+
116+
%-set marker color-%
117+
marker.color = markerColor;
118+
119+
end
120+
121+
%-------------------------------------------------------------------------%
122+
123+
%-MARKER LINE COLOR-%
124+
125+
% marker edge color
126+
edgeColor = geoData.MarkerEdgeColor;
127+
128+
if isnumeric(edgeColor)
129+
lineColor = sprintf('rgb(%f,%f,%f)', 255 * edgeColor);
130+
131+
else
132+
switch edgeColor
133+
134+
case 'none'
135+
136+
lineColor = 'rgba(0,0,0,0)';
137+
138+
case 'auto'
139+
140+
% TODO
141+
142+
case 'flat'
143+
144+
cData = geoData.CData;
145+
cMap = figureData.Colormap;
146+
ncolors = size(cMap, 1);
147+
148+
for m = 1:length(cData)
149+
colorValue = max( min( cData(m), axisData.CLim(2) ), axisData.CLim(1) );
150+
scaleFactor = (colorValue - axisData.CLim(1)) / diff(axisData.CLim);
151+
rgbColor = 255 * cMap( 1+floor(scaleFactor*(ncolors-1)), : );
152+
lineColor{m} = sprintf('rgb(%f,%f,%f)', rgbColor);
153+
end
154+
155+
end
156+
end
157+
158+
if filledMarker
159+
marker.line.color = lineColor;
160+
else
161+
marker.color = lineColor;
162+
end
163+
164+
%-------------------------------------------------------------------------%
165+
166+
end

0 commit comments

Comments
 (0)