Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

revise plot(MeshLine1) #676

Closed
gdmcbain opened this issue Jul 27, 2021 · 2 comments · Fixed by #692
Closed

revise plot(MeshLine1) #676

gdmcbain opened this issue Jul 27, 2021 · 2 comments · Fixed by #692
Labels

Comments

@gdmcbain
Copy link
Contributor

Some questions about plot(MeshLine), viz.

@plot.register(MeshLine)
def plot_meshline(m: MeshLine, z: ndarray, **kwargs):

were raised in working on the first unsteady one-dimensional example. #674

Because efficiently animating evolving solutions in matplotlib involves something like matplotlib.lines.Line2D.set_data, as in the existing two-dimensional unsteady example

field.set_array(u)

one needs to know the structure of the data used in the original plot of the initial condition. Whereas this is just the solution's nodal DoFs in two dimensions

ax = plot(mesh, u_init[basis.nodal_dofs.flatten()], shading='gouraud')

field.set_array(u[basis.nodal_dofs.flatten()])

in one dimension, the initial plot is delegated to plot_meshline which has some rather involved preprocessing

for y1, y2, s, t in zip(z[m.t[0]],
z[m.t[1]],
m.p[0, m.t[0]],
m.p[0, m.t[1]]):
xs.append(s)
xs.append(t)
xs.append(None)
ys.append(y1)
ys.append(y2)
ys.append(None)

which needs to be equally applied at each step.

There was a proposal to extract this as a method MeshLine1.segment_data in ad43d00 but this is where questions were raised:

I don't know if this is needed though? Isn't ax.plot(m.p[0], z) enough? This could be just some copypasta from draw_mesh2d where appending None gives faster performance.

The main work of the first unsteady one-dimensional example #674 is to demonstrate how post-processing works in one dimension because one dimension is different to two and three, so if one-dimensional plotting should generally be done differently, that should be sorted out before writing the example.

By

    ax.plot(m.p[0], z)

or a variation with np.argsort, do you mean dispensing with visuals.matplotlib.plot_meshline? I guess that that works well enough in

ax.plot(x, legendre(n)(x), color=dots.get_color())

@gdmcbain
Copy link
Contributor Author

Besides 94dc1b8, I've been thinking about another idea to get the various implementations of skfem.visuals.matplotlib.plot to behave more similarly. (The motivation for this is so that one can begin a new project in say one dimension, get it going quickly, and then change up to two or three dimensions, only having to change the least amount of dimension-specific code. Similarly for beginning with P1 elements and changing to something higher order or more exotic.) To be more concrete, I'd like to reduce the differences between exx 19

ax = plot(mesh, u_init[basis.nodal_dofs.flatten()], shading='gouraud')
title = ax.set_title('t = 0.00')
field = ax.get_children()[0] # vertex-based temperature-colour

field.set_array(u[basis.nodal_dofs.flatten()])

and 39 (which doesn't currently use skfem.visuals)

line = ax.plot(xi, u_init[sorting], "bo", label="skfem")[0]

line.set_ydata(u[sorting])

So the still vague idea is that if ax is the matplotlib.axes.Axes returned by skfem.visuals.matplotlib.plot, we might define a method for ax.get_children()[0] that handles updating. Then in ex19 we might update with something like ax.update_plot_element(u[basis.nodal_dofs.flatten()]) and under the hood it would do the equivalent of calling field.set_array(u[basis.nodal_dofs.flatten()]) and in ex39 ax.update_plot_element would effectively call line.set_ydata with the same kind of data (flattened, restricted to nodes, sorted, &c.) as originally passed to plot. I envisage implementing this by defining a closure inside, e.g. plot_meshline, and attaching it as a method to ax before returning it.

@gdmcbain
Copy link
Contributor Author

…yes, like the addition of the .show method in

ax = plot(self, *args, **kwargs)
ax.show = show
return ax

@kinnala kinnala added the bug label Aug 30, 2021
kinnala added a commit that referenced this issue Aug 31, 2021
* Support elements not in BOUNDARY_ELEMENT_MAP
* Better __repr__ for Mesh
* Move Mesh.to_dict/from_dict to skfem.io.json
* Make FacetBasis a simple alias to BoundaryFacetBasis
* Remove some old kwarg types supported by asm; interpolate by default
* Add DG mesh types and MeshDG mixin
* Fix MappingIsoparametric 1D scaling, add another test
* Fix test and then mypy differently
* Test init_refdom
* Simplify plot_meshline, fixes #676
* Add quadratic sphere cycle test
* Support MeshHex2 in skfem.io.meshio
* Add draw methods for quadratic 2D meshes
* Allow summing two COOData
* Add NotImplementedError for some features in MeshDG and Mesh2D2
@gdmcbain gdmcbain mentioned this issue Nov 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants