How do I programmatically duplicate a view display? I have a view (my_view) with the following displays: 


master
page_1


I am looking for a way to programmatically duplicate page_1.

    $view = Views::getView('my_view');
    $storage = $view-&gt;storage;
    $display = &amp;$storage-&gt;getDisplay('page_1');
    // Create a new display. 
    // Remove some exposed filters from the new display.
    // save the view.


How can I achieve this?
The View entity comes with a handy function for duplicating an existing display, ->duplicateDisplayAsType().  

->duplicateDisplayAsType() requires 2 arguments--ID of the display to duplicate &amp; new display's type.  First one is self-explanatory--if you want to duplicate something, you need to know what you want to duplicate (visit a View and look at the URL for the unique ID).  For the second arg, a View Display needs to be of a certain type--page, block, feed, etc.  

Finally, we have something like below:

$commentView = \Drupal::entityTypeManager()-&gt;getStorage('view')-&gt;load('comment');

// -&gt;duplicateDisplayAsType() returns the new display's ID so it's not 100% necessary
//   to assign the return val to a variable.
$new_page = $commentView-&gt;duplicateDisplayAsType('page_published', 'page');
$new_block = $commentView-&gt;duplicateDisplayAsType('page_published', 'block');

$commentView-&gt;save();


Above, I am using the default 'Comments' view and duplicating the 'page_published' Display as both a new page and new block.  Try copy pasting the above code into a Controller and triggering the controller method once and visit the View to see your new Displays.

Finally, as with most entity operations, you'll want to ->save() it afterwards.  

Note:  Using (presumably) \Drupal\views\Views::getView() will return a ViewExecutable--aka a configured View which is used for generating the actual output.  You cannot edit the View's config via ViewExecutable.  Above, I am using the entityTypeManager() to query for a View so I can retrieve the actual Entity so we can modify its configuration.  The above code can act as boilerplate--try switching out values to achieve your desired goal.

EDIT: To answer your question more definitively, the above example code could be translated to match your code snippet:

$view = \Drupal::entityTypeManager()-&gt;getStorage('view')-&gt;load('my_view');
$new_page = $view-&gt;duplicateDisplayAsType('page_1', 'page');

$view-&gt;save();


Edit 2:  Sorry, I didn't answer your second part--how do we modify the display after duplicating.  This may not be the most efficient way so someone please tell me if there is a better way to do it.  Luckily you want to only remove a filter.   Because filters are not yet OOP, they're just giant arrays with specific keys you need to set.  This part does get a bit more complicated.

There is one thing you need to keep in mind though--the default display will apply its display_options across all displays unless you override them in the 'defaults' array on the specific display configuration.  You can override defaults for each display_option so you can still inherit defaults for some properties while overriding others.

For comments, specifically, the filters are all placed on the 'default'.  Out of the box, the Comments view only comes with the page_published display.  Let's say we want to duplicate the page_published display, copy over the filters from the original display, remove its default filters, and then array_pop() one of the filters off our new display.  So starting from scratch again:

$view = \Drupal::entityTypeManager()-&gt;getStorage('view')-&gt;load('comment');
$new_display_id = $view-&gt;duplicateDisplayAsType('page_published', 'page');
// Must use the getter--the display property is protected
// We assign by reference because there is no setter--we cannot set the display
//   options again after modifying but we can modify the referenced var to change
//   the original values
$new_display = &amp;$view-&gt;getDisplay($new_display_id);
$default_display = &amp;$view-&gt;getDisplay('default');
// Copy the filters from the 'default' to the new display
$new_display['display_options']['filters'] = $default_display['display_options']['filters'];
$new_display['display_options']['filter_groups'] = $default_display['display_options']['filter_groups'];

// Tell Views not to use the defaults for these two specific properties
$new_display['display_options']['defaults'] = [
  'filters' =&gt; FALSE,
  'filter_groups' =&gt; FALSE,
];

// For demonstration purposes, we remove 1 filter from our copied over filters
array_pop($new_display['display_options']['filters']);

$view-&gt;save();


You should see a page exactly like the page_published except it should be missing 1 filter.