Skip to content

Commit e0e185e

Browse files
authored
Added figure to_ordered_dict method (#1167)
Adds a new BaseFigure method, to_ordered_dict. This builds and returns a representation of the figure as a nested structure of OrderedDict and list instances. The OrderedDict keys are sorted alphabetically. This makes it possible for library users to iterate over the nested structure of a figure in a deterministic order. This method takes the place of the Figure.get_ordered method in plotly.py < 3.0.0. See #1158 for some discussion * Added to_ordered_dict * Use setitem rather than setattr syntax in graph object constructors This has less indirection, and seems to work around a strange nose testing bug with frames.
1 parent 7ddd1c9 commit e0e185e

File tree

577 files changed

+6276
-5525
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

577 files changed

+6276
-5525
lines changed

Diff for: codegen/datatypes.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ def __init__(self""")
246246
name_prop = subtype_node.name_property
247247
buffer.write(f"""
248248
_v = arg.pop('{name_prop}', None)
249-
self.{name_prop} = {name_prop} if {name_prop} is not None else _v""")
249+
self['{name_prop}'] = {name_prop} \
250+
if {name_prop} is not None else _v""")
250251

251252
# ### Literals ###
252253
if literal_nodes:

Diff for: plotly/basedatatypes.py

+48
Original file line numberDiff line numberDiff line change
@@ -2084,6 +2084,54 @@ def to_plotly_json(self):
20842084
"""
20852085
return self.to_dict()
20862086

2087+
@staticmethod
2088+
def _to_ordered_dict(d, skip_uid=False):
2089+
"""
2090+
Static helper for converting dict or list to structure of ordered
2091+
dictionaries
2092+
"""
2093+
if isinstance(d, dict):
2094+
# d is a dict
2095+
result = collections.OrderedDict()
2096+
for key in sorted(d.keys()):
2097+
if skip_uid and key == 'uid':
2098+
continue
2099+
else:
2100+
result[key] = BaseFigure._to_ordered_dict(
2101+
d[key], skip_uid=skip_uid)
2102+
2103+
elif isinstance(d, list) and d and isinstance(d[0], dict):
2104+
# d is a list of dicts
2105+
result = [BaseFigure._to_ordered_dict(el, skip_uid=skip_uid)
2106+
for el in d]
2107+
else:
2108+
result = d
2109+
2110+
return result
2111+
2112+
def to_ordered_dict(self, skip_uid=True):
2113+
2114+
# Initialize resulting OrderedDict
2115+
# --------------------------------
2116+
result = collections.OrderedDict()
2117+
2118+
# Handle data
2119+
# -----------
2120+
result['data'] = BaseFigure._to_ordered_dict(self._data,
2121+
skip_uid=skip_uid)
2122+
2123+
# Handle layout
2124+
# -------------
2125+
result['layout'] = BaseFigure._to_ordered_dict(self._layout)
2126+
2127+
# Handle frames
2128+
# -------------
2129+
if self._frame_objs:
2130+
frames_props = [frame._props for frame in self._frame_objs]
2131+
result['frames'] = BaseFigure._to_ordered_dict(frames_props)
2132+
2133+
return result
2134+
20872135
# Static helpers
20882136
# --------------
20892137
@staticmethod

Diff for: plotly/graph_objs/_area.py

+22-20
Original file line numberDiff line numberDiff line change
@@ -744,45 +744,47 @@ def __init__(
744744
# Populate data dict with properties
745745
# ----------------------------------
746746
_v = arg.pop('customdata', None)
747-
self.customdata = customdata if customdata is not None else _v
747+
self['customdata'] = customdata if customdata is not None else _v
748748
_v = arg.pop('customdatasrc', None)
749-
self.customdatasrc = customdatasrc if customdatasrc is not None else _v
749+
self['customdatasrc'
750+
] = customdatasrc if customdatasrc is not None else _v
750751
_v = arg.pop('hoverinfo', None)
751-
self.hoverinfo = hoverinfo if hoverinfo is not None else _v
752+
self['hoverinfo'] = hoverinfo if hoverinfo is not None else _v
752753
_v = arg.pop('hoverinfosrc', None)
753-
self.hoverinfosrc = hoverinfosrc if hoverinfosrc is not None else _v
754+
self['hoverinfosrc'] = hoverinfosrc if hoverinfosrc is not None else _v
754755
_v = arg.pop('hoverlabel', None)
755-
self.hoverlabel = hoverlabel if hoverlabel is not None else _v
756+
self['hoverlabel'] = hoverlabel if hoverlabel is not None else _v
756757
_v = arg.pop('ids', None)
757-
self.ids = ids if ids is not None else _v
758+
self['ids'] = ids if ids is not None else _v
758759
_v = arg.pop('idssrc', None)
759-
self.idssrc = idssrc if idssrc is not None else _v
760+
self['idssrc'] = idssrc if idssrc is not None else _v
760761
_v = arg.pop('legendgroup', None)
761-
self.legendgroup = legendgroup if legendgroup is not None else _v
762+
self['legendgroup'] = legendgroup if legendgroup is not None else _v
762763
_v = arg.pop('marker', None)
763-
self.marker = marker if marker is not None else _v
764+
self['marker'] = marker if marker is not None else _v
764765
_v = arg.pop('name', None)
765-
self.name = name if name is not None else _v
766+
self['name'] = name if name is not None else _v
766767
_v = arg.pop('opacity', None)
767-
self.opacity = opacity if opacity is not None else _v
768+
self['opacity'] = opacity if opacity is not None else _v
768769
_v = arg.pop('r', None)
769-
self.r = r if r is not None else _v
770+
self['r'] = r if r is not None else _v
770771
_v = arg.pop('rsrc', None)
771-
self.rsrc = rsrc if rsrc is not None else _v
772+
self['rsrc'] = rsrc if rsrc is not None else _v
772773
_v = arg.pop('selectedpoints', None)
773-
self.selectedpoints = selectedpoints if selectedpoints is not None else _v
774+
self['selectedpoints'
775+
] = selectedpoints if selectedpoints is not None else _v
774776
_v = arg.pop('showlegend', None)
775-
self.showlegend = showlegend if showlegend is not None else _v
777+
self['showlegend'] = showlegend if showlegend is not None else _v
776778
_v = arg.pop('stream', None)
777-
self.stream = stream if stream is not None else _v
779+
self['stream'] = stream if stream is not None else _v
778780
_v = arg.pop('t', None)
779-
self.t = t if t is not None else _v
781+
self['t'] = t if t is not None else _v
780782
_v = arg.pop('tsrc', None)
781-
self.tsrc = tsrc if tsrc is not None else _v
783+
self['tsrc'] = tsrc if tsrc is not None else _v
782784
_v = arg.pop('uid', None)
783-
self.uid = uid if uid is not None else _v
785+
self['uid'] = uid if uid is not None else _v
784786
_v = arg.pop('visible', None)
785-
self.visible = visible if visible is not None else _v
787+
self['visible'] = visible if visible is not None else _v
786788

787789
# Read-only literals
788790
# ------------------

Diff for: plotly/graph_objs/_bar.py

+60-54
Original file line numberDiff line numberDiff line change
@@ -2063,113 +2063,119 @@ def __init__(
20632063
# Populate data dict with properties
20642064
# ----------------------------------
20652065
_v = arg.pop('base', None)
2066-
self.base = base if base is not None else _v
2066+
self['base'] = base if base is not None else _v
20672067
_v = arg.pop('basesrc', None)
2068-
self.basesrc = basesrc if basesrc is not None else _v
2068+
self['basesrc'] = basesrc if basesrc is not None else _v
20692069
_v = arg.pop('cliponaxis', None)
2070-
self.cliponaxis = cliponaxis if cliponaxis is not None else _v
2070+
self['cliponaxis'] = cliponaxis if cliponaxis is not None else _v
20712071
_v = arg.pop('constraintext', None)
2072-
self.constraintext = constraintext if constraintext is not None else _v
2072+
self['constraintext'
2073+
] = constraintext if constraintext is not None else _v
20732074
_v = arg.pop('customdata', None)
2074-
self.customdata = customdata if customdata is not None else _v
2075+
self['customdata'] = customdata if customdata is not None else _v
20752076
_v = arg.pop('customdatasrc', None)
2076-
self.customdatasrc = customdatasrc if customdatasrc is not None else _v
2077+
self['customdatasrc'
2078+
] = customdatasrc if customdatasrc is not None else _v
20772079
_v = arg.pop('dx', None)
2078-
self.dx = dx if dx is not None else _v
2080+
self['dx'] = dx if dx is not None else _v
20792081
_v = arg.pop('dy', None)
2080-
self.dy = dy if dy is not None else _v
2082+
self['dy'] = dy if dy is not None else _v
20812083
_v = arg.pop('error_x', None)
2082-
self.error_x = error_x if error_x is not None else _v
2084+
self['error_x'] = error_x if error_x is not None else _v
20832085
_v = arg.pop('error_y', None)
2084-
self.error_y = error_y if error_y is not None else _v
2086+
self['error_y'] = error_y if error_y is not None else _v
20852087
_v = arg.pop('hoverinfo', None)
2086-
self.hoverinfo = hoverinfo if hoverinfo is not None else _v
2088+
self['hoverinfo'] = hoverinfo if hoverinfo is not None else _v
20872089
_v = arg.pop('hoverinfosrc', None)
2088-
self.hoverinfosrc = hoverinfosrc if hoverinfosrc is not None else _v
2090+
self['hoverinfosrc'] = hoverinfosrc if hoverinfosrc is not None else _v
20892091
_v = arg.pop('hoverlabel', None)
2090-
self.hoverlabel = hoverlabel if hoverlabel is not None else _v
2092+
self['hoverlabel'] = hoverlabel if hoverlabel is not None else _v
20912093
_v = arg.pop('hovertext', None)
2092-
self.hovertext = hovertext if hovertext is not None else _v
2094+
self['hovertext'] = hovertext if hovertext is not None else _v
20932095
_v = arg.pop('hovertextsrc', None)
2094-
self.hovertextsrc = hovertextsrc if hovertextsrc is not None else _v
2096+
self['hovertextsrc'] = hovertextsrc if hovertextsrc is not None else _v
20952097
_v = arg.pop('ids', None)
2096-
self.ids = ids if ids is not None else _v
2098+
self['ids'] = ids if ids is not None else _v
20972099
_v = arg.pop('idssrc', None)
2098-
self.idssrc = idssrc if idssrc is not None else _v
2100+
self['idssrc'] = idssrc if idssrc is not None else _v
20992101
_v = arg.pop('insidetextfont', None)
2100-
self.insidetextfont = insidetextfont if insidetextfont is not None else _v
2102+
self['insidetextfont'
2103+
] = insidetextfont if insidetextfont is not None else _v
21012104
_v = arg.pop('legendgroup', None)
2102-
self.legendgroup = legendgroup if legendgroup is not None else _v
2105+
self['legendgroup'] = legendgroup if legendgroup is not None else _v
21032106
_v = arg.pop('marker', None)
2104-
self.marker = marker if marker is not None else _v
2107+
self['marker'] = marker if marker is not None else _v
21052108
_v = arg.pop('name', None)
2106-
self.name = name if name is not None else _v
2109+
self['name'] = name if name is not None else _v
21072110
_v = arg.pop('offset', None)
2108-
self.offset = offset if offset is not None else _v
2111+
self['offset'] = offset if offset is not None else _v
21092112
_v = arg.pop('offsetsrc', None)
2110-
self.offsetsrc = offsetsrc if offsetsrc is not None else _v
2113+
self['offsetsrc'] = offsetsrc if offsetsrc is not None else _v
21112114
_v = arg.pop('opacity', None)
2112-
self.opacity = opacity if opacity is not None else _v
2115+
self['opacity'] = opacity if opacity is not None else _v
21132116
_v = arg.pop('orientation', None)
2114-
self.orientation = orientation if orientation is not None else _v
2117+
self['orientation'] = orientation if orientation is not None else _v
21152118
_v = arg.pop('outsidetextfont', None)
2116-
self.outsidetextfont = outsidetextfont if outsidetextfont is not None else _v
2119+
self['outsidetextfont'
2120+
] = outsidetextfont if outsidetextfont is not None else _v
21172121
_v = arg.pop('r', None)
2118-
self.r = r if r is not None else _v
2122+
self['r'] = r if r is not None else _v
21192123
_v = arg.pop('rsrc', None)
2120-
self.rsrc = rsrc if rsrc is not None else _v
2124+
self['rsrc'] = rsrc if rsrc is not None else _v
21212125
_v = arg.pop('selected', None)
2122-
self.selected = selected if selected is not None else _v
2126+
self['selected'] = selected if selected is not None else _v
21232127
_v = arg.pop('selectedpoints', None)
2124-
self.selectedpoints = selectedpoints if selectedpoints is not None else _v
2128+
self['selectedpoints'
2129+
] = selectedpoints if selectedpoints is not None else _v
21252130
_v = arg.pop('showlegend', None)
2126-
self.showlegend = showlegend if showlegend is not None else _v
2131+
self['showlegend'] = showlegend if showlegend is not None else _v
21272132
_v = arg.pop('stream', None)
2128-
self.stream = stream if stream is not None else _v
2133+
self['stream'] = stream if stream is not None else _v
21292134
_v = arg.pop('t', None)
2130-
self.t = t if t is not None else _v
2135+
self['t'] = t if t is not None else _v
21312136
_v = arg.pop('text', None)
2132-
self.text = text if text is not None else _v
2137+
self['text'] = text if text is not None else _v
21332138
_v = arg.pop('textfont', None)
2134-
self.textfont = textfont if textfont is not None else _v
2139+
self['textfont'] = textfont if textfont is not None else _v
21352140
_v = arg.pop('textposition', None)
2136-
self.textposition = textposition if textposition is not None else _v
2141+
self['textposition'] = textposition if textposition is not None else _v
21372142
_v = arg.pop('textpositionsrc', None)
2138-
self.textpositionsrc = textpositionsrc if textpositionsrc is not None else _v
2143+
self['textpositionsrc'
2144+
] = textpositionsrc if textpositionsrc is not None else _v
21392145
_v = arg.pop('textsrc', None)
2140-
self.textsrc = textsrc if textsrc is not None else _v
2146+
self['textsrc'] = textsrc if textsrc is not None else _v
21412147
_v = arg.pop('tsrc', None)
2142-
self.tsrc = tsrc if tsrc is not None else _v
2148+
self['tsrc'] = tsrc if tsrc is not None else _v
21432149
_v = arg.pop('uid', None)
2144-
self.uid = uid if uid is not None else _v
2150+
self['uid'] = uid if uid is not None else _v
21452151
_v = arg.pop('unselected', None)
2146-
self.unselected = unselected if unselected is not None else _v
2152+
self['unselected'] = unselected if unselected is not None else _v
21472153
_v = arg.pop('visible', None)
2148-
self.visible = visible if visible is not None else _v
2154+
self['visible'] = visible if visible is not None else _v
21492155
_v = arg.pop('width', None)
2150-
self.width = width if width is not None else _v
2156+
self['width'] = width if width is not None else _v
21512157
_v = arg.pop('widthsrc', None)
2152-
self.widthsrc = widthsrc if widthsrc is not None else _v
2158+
self['widthsrc'] = widthsrc if widthsrc is not None else _v
21532159
_v = arg.pop('x', None)
2154-
self.x = x if x is not None else _v
2160+
self['x'] = x if x is not None else _v
21552161
_v = arg.pop('x0', None)
2156-
self.x0 = x0 if x0 is not None else _v
2162+
self['x0'] = x0 if x0 is not None else _v
21572163
_v = arg.pop('xaxis', None)
2158-
self.xaxis = xaxis if xaxis is not None else _v
2164+
self['xaxis'] = xaxis if xaxis is not None else _v
21592165
_v = arg.pop('xcalendar', None)
2160-
self.xcalendar = xcalendar if xcalendar is not None else _v
2166+
self['xcalendar'] = xcalendar if xcalendar is not None else _v
21612167
_v = arg.pop('xsrc', None)
2162-
self.xsrc = xsrc if xsrc is not None else _v
2168+
self['xsrc'] = xsrc if xsrc is not None else _v
21632169
_v = arg.pop('y', None)
2164-
self.y = y if y is not None else _v
2170+
self['y'] = y if y is not None else _v
21652171
_v = arg.pop('y0', None)
2166-
self.y0 = y0 if y0 is not None else _v
2172+
self['y0'] = y0 if y0 is not None else _v
21672173
_v = arg.pop('yaxis', None)
2168-
self.yaxis = yaxis if yaxis is not None else _v
2174+
self['yaxis'] = yaxis if yaxis is not None else _v
21692175
_v = arg.pop('ycalendar', None)
2170-
self.ycalendar = ycalendar if ycalendar is not None else _v
2176+
self['ycalendar'] = ycalendar if ycalendar is not None else _v
21712177
_v = arg.pop('ysrc', None)
2172-
self.ysrc = ysrc if ysrc is not None else _v
2178+
self['ysrc'] = ysrc if ysrc is not None else _v
21732179

21742180
# Read-only literals
21752181
# ------------------

0 commit comments

Comments
 (0)